diff options
author | Steve Dower <steve.dower@python.org> | 2019-08-21 22:27:33 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-21 22:27:33 (GMT) |
commit | df2d4a6f3d5da2839c4fc11d31511c8e028daf2c (patch) | |
tree | e60154de9e835976aed87ab51ac3d5d9fda7f45f /Python/fileutils.c | |
parent | bcc446f525421156fe693139140e7051d000592e (diff) | |
download | cpython-df2d4a6f3d5da2839c4fc11d31511c8e028daf2c.zip cpython-df2d4a6f3d5da2839c4fc11d31511c8e028daf2c.tar.gz cpython-df2d4a6f3d5da2839c4fc11d31511c8e028daf2c.tar.bz2 |
bpo-37834: Normalise handling of reparse points on Windows (GH-15231)
bpo-37834: Normalise handling of reparse points on Windows
* ntpath.realpath() and nt.stat() will traverse all supported reparse points (previously was mixed)
* nt.lstat() will let the OS traverse reparse points that are not name surrogates (previously would not traverse any reparse point)
* nt.[l]stat() will only set S_IFLNK for symlinks (previous behaviour)
* nt.readlink() will read destinations for symlinks and junction points only
bpo-1311: os.path.exists('nul') now returns True on Windows
* nt.stat('nul').st_mode is now S_IFCHR (previously was an error)
Diffstat (limited to 'Python/fileutils.c')
-rw-r--r-- | Python/fileutils.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/Python/fileutils.c b/Python/fileutils.c index 55bc194..36a3c99 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -878,7 +878,12 @@ _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); result->st_nlink = info->nNumberOfLinks; result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow; - if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { + /* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will + open other name surrogate reparse points without traversing them. To + detect/handle these, check st_file_attributes and st_reparse_tag. */ + result->st_reparse_tag = reparse_tag; + if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && + reparse_tag == IO_REPARSE_TAG_SYMLINK) { /* first clear the S_IFMT bits */ result->st_mode ^= (result->st_mode & S_IFMT); /* now set the bits that make this a symlink */ |