diff options
author | Brett Cannon <bcannon@gmail.com> | 2004-07-10 22:55:15 (GMT) |
---|---|---|
committer | Brett Cannon <bcannon@gmail.com> | 2004-07-10 22:55:15 (GMT) |
commit | f50299c3787757bfe5d637f5de6d4b995d6beeb0 (patch) | |
tree | c22c127c41a0e605836fd68ff1b09b351559139a /Lib | |
parent | 711e7d97e4bebec002233e7caa72fc43ffba06a5 (diff) | |
download | cpython-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.py | 36 |
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 |