mirror of
https://github.com/python/cpython.git
synced 2025-10-17 04:08:28 +00:00
gh-82367: Use FindFirstFile
Win32 API in ntpath.realpath()
(GH-110298)
* Use `FindFirstFile` Win32 API to fix a bug where `ntpath.realpath()` breaks out of traversing a series of paths where a (handled) `ERROR_ACCESS_DENIED` or `ERROR_SHARING_VIOLATION` occurs. * Update docs to reflect that `ntpath.realpath()` eliminates MS-DOS style names.
This commit is contained in:
parent
2cb62c6437
commit
d33aa18f15
8 changed files with 132 additions and 8 deletions
|
@ -2,6 +2,7 @@ import inspect
|
|||
import ntpath
|
||||
import os
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
import warnings
|
||||
|
@ -637,6 +638,48 @@ class TestNtpath(NtpathTestCase):
|
|||
with os_helper.change_cwd(test_dir_short):
|
||||
self.assertPathEqual(test_file_long, ntpath.realpath("file.txt"))
|
||||
|
||||
@unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname')
|
||||
def test_realpath_permission(self):
|
||||
# Test whether python can resolve the real filename of a
|
||||
# shortened file name even if it does not have permission to access it.
|
||||
ABSTFN = ntpath.realpath(os_helper.TESTFN)
|
||||
|
||||
os_helper.unlink(ABSTFN)
|
||||
os_helper.rmtree(ABSTFN)
|
||||
os.mkdir(ABSTFN)
|
||||
self.addCleanup(os_helper.rmtree, ABSTFN)
|
||||
|
||||
test_file = ntpath.join(ABSTFN, "LongFileName123.txt")
|
||||
test_file_short = ntpath.join(ABSTFN, "LONGFI~1.TXT")
|
||||
|
||||
with open(test_file, "wb") as f:
|
||||
f.write(b"content")
|
||||
# Automatic generation of short names may be disabled on
|
||||
# NTFS volumes for the sake of performance.
|
||||
# They're not supported at all on ReFS and exFAT.
|
||||
subprocess.run(
|
||||
# Try to set the short name manually.
|
||||
['fsutil.exe', 'file', 'setShortName', test_file, 'LONGFI~1.TXT'],
|
||||
creationflags=subprocess.DETACHED_PROCESS
|
||||
)
|
||||
|
||||
try:
|
||||
self.assertPathEqual(test_file, ntpath.realpath(test_file_short))
|
||||
except AssertionError:
|
||||
raise unittest.SkipTest('the filesystem seems to lack support for short filenames')
|
||||
|
||||
# Deny the right to [S]YNCHRONIZE on the file to
|
||||
# force nt._getfinalpathname to fail with ERROR_ACCESS_DENIED.
|
||||
p = subprocess.run(
|
||||
['icacls.exe', test_file, '/deny', '*S-1-5-32-545:(S)'],
|
||||
creationflags=subprocess.DETACHED_PROCESS
|
||||
)
|
||||
|
||||
if p.returncode:
|
||||
raise unittest.SkipTest('failed to deny access to the test file')
|
||||
|
||||
self.assertPathEqual(test_file, ntpath.realpath(test_file_short))
|
||||
|
||||
def test_expandvars(self):
|
||||
with os_helper.EnvironmentVarGuard() as env:
|
||||
env.clear()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue