Uh oh!
There was an error while loading. Please reload this page.
gh-110495: ensure ntpath.realpath() result is a final, normalized pathname. - #110751
gh-110495: ensure ntpath.realpath() result is a final, normalized pathname.#110751moonsikpark wants to merge 4 commits into
ntpath.realpath() result is a final, normalized pathname.#110751Conversation
moonsikpark
commented
Oct 12, 2023
@eryksun can you review this? |
encukou
commented
Mar 8, 2024
cc @serhiy-storchaka (os.path expert) & @barneygale (with the reproducer in the issue, |
Uh oh!
There was an error while loading. Please reload this page.
1f8656e to
3ae56f0Compare…-normalized-pathname
I'm not having much luck getting this to work with a common def_getfinalpathname_nonstrict(path):
# These error codes indicate that we should stop resolving the# path and return the value we currently have.allowed_winerror= (
1, # ERROR_INVALID_FUNCTION2, # ERROR_FILE_NOT_FOUND3, # ERROR_DIRECTORY_NOT_FOUND5, # ERROR_ACCESS_DENIED21, # ERROR_NOT_READY (e.g. drive with no media)32, # ERROR_SHARING_VIOLATION (e.g. NTFS paging file)50, # ERROR_NOT_SUPPORTED53, # ERROR_BAD_NETPATH65, # ERROR_NETWORK_ACCESS_DENIED67, # ERROR_BAD_NET_NAME (e.g. remote server unavailable)87, # ERROR_INVALID_PARAMETER123, # ERROR_INVALID_NAME161, # ERROR_BAD_PATHNAME1920, # ERROR_CANT_ACCESS_FILE1921, # ERROR_CANT_RESOLVE_FILENAME (e.g. can't follow symlink)
)
# Non-strict algorithm is to find as much of the target# directory as we can and join the rest.tail=path[:0]
seen=set()
whilepathandnormcase(path) notinseen:
seen.add(normcase(path))
try:
path=_getfinalpathname(path)
returnjoin(path, tail) iftailelsepathexceptOSErrorasex:
ifex.winerrornotinallowed_winerror:
raise# Split off the base name, and break if it's root.parent_path, name=split(path)
ifnotname:
breaktry:
# Try resolving the final component as a link. If# successful, continue resolving the real path.new_path=_readlink_deep(path)
ifnew_path!=path:
path=new_pathcontinueexceptOSError:
pass# For some error cases, try to get the real name from# the directory entry.ifex.winerrorin (1, 5, 32, 50, 87, 1920, 1921):
try:
name=_findfirstfile(path)
exceptOSError:
passpath=parent_pathtail=join(name, tail) iftailelsenameifpath:
returnjoin(path, tail) iftailelsepathreturntail |
eryksun
commented
Jun 18, 2024
Some of the checks in cpython/Lib/test/test_ntpath.py Lines 471 to 480 in 73dc1c6 New checks: self.assertPathEqual(ntpath.realpath(r"broken1"),
ABSTFN+r"\missing\bar")
self.assertPathEqual(ntpath.realpath(r"broken1\baz"),
ABSTFN+r"\missing\bar\baz")
self.assertPathEqual(ntpath.realpath("broken2"),
ABSTFN+r"\missing")
self.assertPathEqual(ntpath.realpath("broken3"),
ABSTFN+r"\missing")The corresponding |
This PR is stale because it has been open for 30 days with no activity. |
By not breaking out of the loop when
_readlink_deep()is successful, we can ensure that the result ofntpath.realpath()is a final, normalized pathname.ntpath.realpath()result is a final, normalized pathname. #110495