GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `os.path.realpath()` on Windows misresolves a broken symlink reached through a directory symlink · Issue #160506 · python/cpython

os.path.realpath() on Windows misresolves a broken symlink reached through a directory symlink #160506

New issue
Copy link
New issue
Copy link
Closed
#160507
Closed
os.path.realpath() on Windows misresolves a broken symlink reached through a directory symlink#160506
#160507
Copy link
Assignees
gpshead
Labels
OS-windowsstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-securityA security issueA security issue

Description

@gpshead
gpshead
opened on Oct 23, 2026
Issue body actions

Bug report

Bug description:

On Windows, os.path.realpath() returns the wrong path for a broken relative symlink when the path used to reach it goes through a symlink to a directory. ntpath._readlink_deep() joins the link target to dirname() of the path as given, so a .. in the target removes the directory link's name instead of going up from the directory that contains the link. The join dates from bpo-38453 (GH-16967).

tarfile's data and tar extraction filters use this result to decide where a member will be written. Whoever supplies the archive can make extractall() create a new file outside the destination directory, in a directory that already exists, when the extracting process is able to create symlinks.

# Windows, with permission to create symlinks
import os
os.makedirs(r"C:\work\out")
os.symlink(".", r"C:\work\out\alias", target_is_directory=True)
os.symlink(r"..\outside\new.txt", r"C:\work\out\link")
print(os.path.realpath(r"C:\work\out\link"))
print(os.path.realpath(r"C:\work\out\alias\link"))

Both names are the same link, so both lines should be C:\work\outside\new.txt; the second is C:\work\out\outside\new.txt. Opening either name for writing creates C:\work\outside\new.txt.

An archive with the members alias -> ., alias/link -> ../outside/new.txt and a regular file alias/link is extracted by extractall(r"C:\work\out", filter="data") without error and the file's content ends up in C:\work\outside\new.txt. The same archive with the regular file named link raises OutsideDestinationError.

I have not run this on Windows. The output above comes from running the Windows branch of Lib/ntpath.py and Lib/tarfile.py from main on Linux over stand-ins for the nt functions, and from reading the code. test_realpath_broken_symlinks in test_ntpath already asserts the textual join (broken2, broken3). gh-88102, gh-85035 and gh-110495 are related realpath() issues but do not cover this case.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Other

Linked PRs

  • gh-160506: Fix ntpath.realpath() for broken links via directory links #160507
  • [3.15] gh-160506: Fix ntpath.realpath() for broken links via directory links (GH-160507) #161026
  • [3.14] gh-160506: Fix ntpath.realpath() for broken links via directory links (GH-160507) #161027
  • [3.13] gh-160506: Fix ntpath.realpath() for broken links via directory links (GH-160507) #161028
  • [3.12] gh-160506: Fix ntpath.realpath() for broken links via directory links (GH-160507) #161029
  • [3.11] gh-160506: Fix ntpath.realpath() for broken links via directory links (GH-160507) #161030

Activity

  1. gpshead
    self-assigned this
    on Oct 23, 2026
  2. gpshead
    added
    type-securityA security issueA security issue
    OS-windows
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Oct 23, 2026
  3. gpshead
    added a commit that references this issue on Oct 31, 2026

    gh-160506: Fix ntpath.realpath() for broken links via directory links (…

    65665a4
  4. gpshead
    closed this as completedin #160507on Oct 31, 2026
  5. gpshead
    added a commit that references this issue on Oct 31, 2026

    [3.15] gh-160506: Fix ntpath.realpath() for broken links via director…

    18e07bf
  6. gpshead
    added a commit that references this issue on Nov 9, 2026

    [3.14] gh-160506: Fix ntpath.realpath() for broken links via director…

    dbcf003
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @gpshead
    gpshead

Labels

OS-windowsstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-securityA security issueA security issue

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.