Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f50299c

Browse files
committed
posixpath.realpath() now detects symlink loops and returns the path just before
the loop starts. Closes bug #930024. Thanks AM Kuchling.
1 parent 711e7d9 commit f50299c

2 files changed

Lines changed: 34 additions & 6 deletions

File tree

Lib/posixpath.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -405,13 +405,37 @@ def realpath(filename):
405405
bits = ['/'] + filename.split('/')[1:]
406406
for i in range(2, len(bits)+1):
407407
component = join(*bits[0:i])
408-
if islink(component):
409-
resolved = os.readlink(component)
410-
(dir, file) = split(component)
411-
resolved = normpath(join(dir, resolved))
412-
newpath = join(*([resolved] + bits[i:]))
413-
return realpath(newpath)
408+
# Resolve symbolic links.
409+
if islink(component):
410+
resolved = _resolve_link(component)
411+
if resolved is None:
412+
# Infinite loop -- return original component + rest of the path
413+
return join(*([component] + bits[i:]))
414+
else:
415+
newpath = join(*([resolved] + bits[i:]))
416+
return realpath(newpath)
414417

415418
return filename
416419

420+
421+
def _resolve_link(path):
422+
"""Internal helper function. Takes a path and follows symlinks
423+
until we either arrive at something that isn't a symlink, or
424+
encounter a path we've seen before (meaning that there's a loop).
425+
"""
426+
paths_seen = []
427+
while islink(path):
428+
if path in paths_seen:
429+
# Already seen this path, so we must have a symlink loop
430+
return None
431+
paths_seen.append(path)
432+
# Resolve where the link points to
433+
resolved = os.readlink(path)
434+
if not abspath(resolved):
435+
dir = dirname(path)
436+
path = normpath(join(dir, resolved))
437+
else:
438+
path = normpath(resolved)
439+
return path
440+
417441
supports_unicode_filenames = False

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ Extension modules
2929
Library
3030
-------
3131

32+
- Bug #930024: posixpath.realpath() now handles infinite loops in symlinks by
33+
returning the last point in the path that was not part of any loop. Thanks
34+
AM Kuchling.
35+
3236
- Bug #980327: ntpath not handles compressing erroneous slashes between the
3337
drive letter and the rest of the path. Also clearly handles UNC addresses now
3438
as well. Thanks Paul Moore.

0 commit comments

Comments
 (0)