[Python-checkins] cpython (3.4): Issue #26012: Don't traverse into symlinks for ** pattern in

guido.van.rossum python-checkins at python.org
Wed Jan 6 13:36:38 EST 2016


https://hg.python.org/cpython/rev/18f5b125a863
changeset:   99778:18f5b125a863
branch:      3.4
parent:      99775:bac18cb7b011
user:        Guido van Rossum <guido at python.org>
date:        Wed Jan 06 10:31:33 2016 -0800
summary:
  Issue #26012: Don't traverse into symlinks for ** pattern in pathlib.Path.[r]glob().

files:
  Lib/pathlib.py           |   2 +-
  Lib/test/test_pathlib.py |  19 ++++++++++++++++++-
  Misc/NEWS                |   3 +++
  3 files changed, 22 insertions(+), 2 deletions(-)


diff --git a/Lib/pathlib.py b/Lib/pathlib.py
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -496,7 +496,7 @@
         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
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -1245,7 +1245,7 @@
             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':
@@ -1380,6 +1380,23 @@
         _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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,9 @@
 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.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list