]> granicus.if.org Git - python/commitdiff
posixpath.realpath() now detects symlink loops and returns the path just before
authorBrett Cannon <bcannon@gmail.com>
Sat, 10 Jul 2004 22:55:15 +0000 (22:55 +0000)
committerBrett Cannon <bcannon@gmail.com>
Sat, 10 Jul 2004 22:55:15 +0000 (22:55 +0000)
the loop starts.

Closes bug #930024.  Thanks AM Kuchling.

Lib/posixpath.py
Misc/NEWS

index c117c89934074c9e59e40f4d07edee99ed1b85f9..85a26daee9a159692646d19c6207dbde33fbc873 100644 (file)
@@ -405,13 +405,37 @@ symbolic links encountered in the path."""
     bits = ['/'] + filename.split('/')[1:]
     for i in range(2, len(bits)+1):
         component = join(*bits[0:i])
-        if islink(component):
-            resolved = os.readlink(component)
-            (dir, file) = split(component)
-            resolved = normpath(join(dir, resolved))
-            newpath = join(*([resolved] + bits[i:]))
-            return realpath(newpath)
+        # Resolve symbolic links.
+       if islink(component):
+            resolved = _resolve_link(component)
+            if resolved is None:
+                # Infinite loop -- return original component + rest of the path
+                return join(*([component] + bits[i:]))
+            else:
+                newpath = join(*([resolved] + bits[i:]))
+                return realpath(newpath)
 
     return filename
 
+
+def _resolve_link(path):
+    """Internal helper function.  Takes a path and follows symlinks
+    until we either arrive at something that isn't a symlink, or 
+    encounter a path we've seen before (meaning that there's a loop).
+    """
+    paths_seen = []
+    while islink(path):
+       if path in paths_seen:
+            # Already seen this path, so we must have a symlink loop
+            return None
+       paths_seen.append(path)
+        # Resolve where the link points to
+       resolved = os.readlink(path)
+        if not abspath(resolved):
+            dir = dirname(path)
+            path = normpath(join(dir, resolved))
+        else:
+            path = normpath(resolved)
+    return path
+
 supports_unicode_filenames = False
index 40052977047b2c7201523d9baf94ec8c553d24b9..8260e636efa924db75e545251793bf7f9f8a1e02 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -29,6 +29,10 @@ Extension modules
 Library
 -------
 
+- Bug #930024: posixpath.realpath() now handles infinite loops in symlinks by
+  returning the last point in the path that was not part of any loop.  Thanks
+  AM Kuchling.
+
 - Bug #980327: ntpath not handles compressing erroneous slashes between the
   drive letter and the rest of the path.  Also clearly handles UNC addresses now
   as well.  Thanks Paul Moore.