summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@dropbox.com>2016-01-06 18:36:19 (GMT)
committerGuido van Rossum <guido@dropbox.com>2016-01-06 18:36:19 (GMT)
commite630b6818f28b6c4f8845fbaf2d115bbc3f2b733 (patch)
tree358b6721a493bbcd6ecb51251e6e23b19e0c92a9
parent080169c494e3a7e252d9b43947cbd2576e1a071f (diff)
parent520f297eb4d85a99bee8a22d60c4139b8a443d94 (diff)
downloadcpython-e630b6818f28b6c4f8845fbaf2d115bbc3f2b733.zip
cpython-e630b6818f28b6c4f8845fbaf2d115bbc3f2b733.tar.gz
cpython-e630b6818f28b6c4f8845fbaf2d115bbc3f2b733.tar.bz2
Issue #26012: Don't traverse into symlinks for ** pattern in pathlib.Path.[r]glob(). (Merge 3.5->3.6)
-rw-r--r--Lib/pathlib.py2
-rw-r--r--Lib/test/test_pathlib.py19
-rw-r--r--Misc/NEWS3
3 files changed, 22 insertions, 2 deletions
diff --git a/Lib/pathlib.py b/Lib/pathlib.py
index 1ab656c..d03aede 100644
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -541,7 +541,7 @@ class _RecursiveWildcardSelector(_Selector):
yield parent_path
for name in listdir(parent_path):
path = parent_path._make_child_relpath(name)
- if is_dir(path):
+ if is_dir(path) and not path.is_symlink():
for p in self._iterate_directories(path, is_dir, listdir):
yield p
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
index 167a474..bf77277 100644
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -1241,7 +1241,7 @@ class _BasePathTest(object):
os.symlink('non-existing', join('brokenLink'))
self.dirlink('dirB', join('linkB'))
self.dirlink(os.path.join('..', 'dirB'), join('dirA', 'linkC'))
- # This one goes upwards but doesn't create a loop
+ # This one goes upwards, creating a loop
self.dirlink(os.path.join('..', 'dirB'), join('dirB', 'linkD'))
if os.name == 'nt':
@@ -1437,6 +1437,23 @@ class _BasePathTest(object):
_check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"])
_check(p.rglob("*/*"), ["dirC/dirD/fileD"])
+ @with_symlinks
+ def test_rglob_symlink_loop(self):
+ # Don't get fooled by symlink loops (Issue #26012)
+ P = self.cls
+ p = P(BASE)
+ given = set(p.rglob('*'))
+ expect = {'brokenLink',
+ 'dirA', 'dirA/linkC',
+ 'dirB', 'dirB/fileB', 'dirB/linkD',
+ 'dirC', 'dirC/dirD', 'dirC/dirD/fileD', 'dirC/fileC',
+ 'dirE',
+ 'fileA',
+ 'linkA',
+ 'linkB',
+ }
+ self.assertEqual(given, {p / x for x in expect})
+
def test_glob_dotdot(self):
# ".." is not special in globs
P = self.cls
diff --git a/Misc/NEWS b/Misc/NEWS
index ae2a704..01bce3e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -128,6 +128,9 @@ Core and Builtins
Library
-------
+- Issue #26012: Don't traverse into symlinks for ** pattern in
+ pathlib.Path.[r]glob().
+
- Issue #24120: Ignore PermissionError when traversing a tree with
pathlib.Path.[r]glob(). Patch by Ulrich Petri.