bpo-29248: Fix os.readlink() on Windows (GH-5577)
The PrintNameOffset field of the reparse data buffer
was treated as a number of characters instead of bytes.
(cherry picked from commit 3c34aad4e7
)
Co-authored-by: SSE4 <tomskside@gmail.com>
This commit is contained in:
parent
38b4dd7f83
commit
74ebbaeb56
|
@ -2165,6 +2165,21 @@ class Win32SymlinkTests(unittest.TestCase):
|
|||
finally:
|
||||
os.chdir(orig_dir)
|
||||
|
||||
@unittest.skipUnless(os.path.lexists(r'C:\Users\All Users')
|
||||
and os.path.exists(r'C:\ProgramData'),
|
||||
'Test directories not found')
|
||||
def test_29248(self):
|
||||
# os.symlink() calls CreateSymbolicLink, which creates
|
||||
# the reparse data buffer with the print name stored
|
||||
# first, so the offset is always 0. CreateSymbolicLink
|
||||
# stores the "PrintName" DOS path (e.g. "C:\") first,
|
||||
# with an offset of 0, followed by the "SubstituteName"
|
||||
# NT path (e.g. "\??\C:\"). The "All Users" link, on
|
||||
# the other hand, seems to have been created manually
|
||||
# with an inverted order.
|
||||
target = os.readlink(r'C:\Users\All Users')
|
||||
self.assertTrue(os.path.samefile(target, r'C:\ProgramData'))
|
||||
|
||||
|
||||
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
|
||||
class Win32JunctionTests(unittest.TestCase):
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Fix :func:`os.readlink` on Windows, which was mistakenly treating the
|
||||
``PrintNameOffset`` field of the reparse data buffer as a number of
|
||||
characters instead of bytes. Patch by Craig Holmquist and SSE4.
|
|
@ -7439,11 +7439,11 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
"not a symbolic link");
|
||||
return NULL;
|
||||
}
|
||||
print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
|
||||
rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
|
||||
print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
|
||||
rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
|
||||
|
||||
result = PyUnicode_FromWideChar(print_name,
|
||||
rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
|
||||
rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue