summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2019-08-21 22:52:42 (GMT)
committerGitHub <noreply@github.com>2019-08-21 22:52:42 (GMT)
commit9eb3d5463976068900e94b860ced7e035885835c (patch)
treec97aa41b153e67db42ef4b13a9e20bc0747301f9 /Python
parentc30c869e8dec5eefdee7977943ffa11a8e3c8d75 (diff)
downloadcpython-9eb3d5463976068900e94b860ced7e035885835c.zip
cpython-9eb3d5463976068900e94b860ced7e035885835c.tar.gz
cpython-9eb3d5463976068900e94b860ced7e035885835c.tar.bz2
bpo-37834: Normalise handling of reparse points on Windows (GH-15370)
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')
-rw-r--r--Python/fileutils.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/Python/fileutils.c b/Python/fileutils.c
index 93c093f..30ddd03 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 */