Browse code

Improve symlink-loops detection

Cherry-pick cc78fa170:
Revert 22c60c18c and introduce a better detection
for symlink-loops. For example this is ok:
dir1/
dir2/
symdir -> dir2/
While this is a loop:
dir1/
symdir -> ../dir1/

Michal Ludvig authored on 2013/02/18 17:42:54
Showing 1 changed files
... ...
@@ -23,16 +23,26 @@ def _fswalk_follow_symlinks(path):
23 23
         '''
24 24
         Walk filesystem, following symbolic links (but without recursion), on python2.4 and later
25 25
 
26
-        If a recursive directory link is detected, emit a warning and skip.
26
+        If a symlink directory loop is detected, emit a warning and skip.
27
+        E.g.
28
+        dir1/
29
+             dir2/
30
+                  sym-dir -> ../dir2
27 31
         '''
28 32
         assert os.path.isdir(path) # only designed for directory argument
29
-        walkdirs = [path]
33
+        walkdirs = set([path])
30 34
         for dirpath, dirnames, filenames in os.walk(path):
31
- 		handle_exclude_include_walk(dirpath, dirnames, [])
35
+                handle_exclude_include_walk(dirpath, dirnames, [])
36
+                real_dirpath = os.path.realpath(dirpath)
32 37
                 for dirname in dirnames:
33 38
                         current = os.path.join(dirpath, dirname)
39
+                        real_current = os.path.realpath(current)
34 40
                         if os.path.islink(current):
35
-				walkdirs.append(current)
41
+                                if (real_dirpath == real_current or
42
+                                    real_dirpath.startswith(real_current + os.path.sep)):
43
+                                        warning("Skipping recursively symlinked directory %s" % dirname)
44
+                                else:
45
+                                        walkdirs.add(current)
36 46
         for walkdir in walkdirs:
37 47
 		for dirpath, dirnames, filenames in os.walk(walkdir):
38 48
 			handle_exclude_include_walk(dirpath, dirnames, [])