|
2 | 2 | import ntpath |
3 | 3 | import os |
4 | 4 | import string |
| 5 | +import subprocess |
5 | 6 | import sys |
6 | 7 | import unittest |
7 | 8 | import warnings |
@@ -637,6 +638,48 @@ def test_realpath_cwd(self): |
637 | 638 | with os_helper.change_cwd(test_dir_short): |
638 | 639 | self.assertPathEqual(test_file_long, ntpath.realpath("file.txt")) |
639 | 640 |
|
| 641 | + @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') |
| 642 | + def test_realpath_permission(self): |
| 643 | + # Test whether python can resolve the real filename of a |
| 644 | + # shortened file name even if it does not have permission to access it. |
| 645 | + ABSTFN = ntpath.realpath(os_helper.TESTFN) |
| 646 | + |
| 647 | + os_helper.unlink(ABSTFN) |
| 648 | + os_helper.rmtree(ABSTFN) |
| 649 | + os.mkdir(ABSTFN) |
| 650 | + self.addCleanup(os_helper.rmtree, ABSTFN) |
| 651 | + |
| 652 | + test_file = ntpath.join(ABSTFN, "LongFileName123.txt") |
| 653 | + test_file_short = ntpath.join(ABSTFN, "LONGFI~1.TXT") |
| 654 | + |
| 655 | + with open(test_file, "wb") as f: |
| 656 | + f.write(b"content") |
| 657 | + # Automatic generation of short names may be disabled on |
| 658 | + # NTFS volumes for the sake of performance. |
| 659 | + # They're not supported at all on ReFS and exFAT. |
| 660 | + subprocess.run( |
| 661 | + # Try to set the short name manually. |
| 662 | + ['fsutil.exe', 'file', 'setShortName', test_file, 'LONGFI~1.TXT'], |
| 663 | + creationflags=subprocess.DETACHED_PROCESS |
| 664 | + ) |
| 665 | + |
| 666 | + try: |
| 667 | + self.assertPathEqual(test_file, ntpath.realpath(test_file_short)) |
| 668 | + except AssertionError: |
| 669 | + raise unittest.SkipTest('the filesystem seems to lack support for short filenames') |
| 670 | + |
| 671 | + # Deny the right to [S]YNCHRONIZE on the file to |
| 672 | + # force nt._getfinalpathname to fail with ERROR_ACCESS_DENIED. |
| 673 | + p = subprocess.run( |
| 674 | + ['icacls.exe', test_file, '/deny', '*S-1-5-32-545:(S)'], |
| 675 | + creationflags=subprocess.DETACHED_PROCESS |
| 676 | + ) |
| 677 | + |
| 678 | + if p.returncode: |
| 679 | + raise unittest.SkipTest('failed to deny access to the test file') |
| 680 | + |
| 681 | + self.assertPathEqual(test_file, ntpath.realpath(test_file_short)) |
| 682 | + |
640 | 683 | def test_expandvars(self): |
641 | 684 | with os_helper.EnvironmentVarGuard() as env: |
642 | 685 | env.clear() |
|
0 commit comments