diff options
author | 박문식 <mooonsik.park@gmail.com> | 2023-10-05 14:49:07 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-05 14:49:07 (GMT) |
commit | d33aa18f15de482a01988aabc75907328e1f9c9f (patch) | |
tree | 16b6448d4cfd56a4f5723950aa1bb108b0b644f2 /Lib/test/test_ntpath.py | |
parent | 2cb62c6437fa07e08b4778f7ab9baa5f16ac01f2 (diff) | |
download | cpython-d33aa18f15de482a01988aabc75907328e1f9c9f.zip cpython-d33aa18f15de482a01988aabc75907328e1f9c9f.tar.gz cpython-d33aa18f15de482a01988aabc75907328e1f9c9f.tar.bz2 |
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.
Diffstat (limited to 'Lib/test/test_ntpath.py')
-rw-r--r-- | Lib/test/test_ntpath.py | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index d91dcdf..3e710d1 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -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() |