summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrett Cannon <bcannon@gmail.com>2004-07-10 22:55:15 (GMT)
committerBrett Cannon <bcannon@gmail.com>2004-07-10 22:55:15 (GMT)
commitf50299c3787757bfe5d637f5de6d4b995d6beeb0 (patch)
treec22c127c41a0e605836fd68ff1b09b351559139a /Lib
parent711e7d97e4bebec002233e7caa72fc43ffba06a5 (diff)
downloadcpython-f50299c3787757bfe5d637f5de6d4b995d6beeb0.zip
cpython-f50299c3787757bfe5d637f5de6d4b995d6beeb0.tar.gz
cpython-f50299c3787757bfe5d637f5de6d4b995d6beeb0.tar.bz2
posixpath.realpath() now detects symlink loops and returns the path just before
the loop starts. Closes bug #930024. Thanks AM Kuchling.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/posixpath.py36
1 files changed, 30 insertions, 6 deletions
diff --git a/Lib/posixpath.py b/Lib/posixpath.py
index c117c89..85a26da 100644
--- a/Lib/posixpath.py
+++ b/Lib/posixpath.py
@@ -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