From 7829ebfebd6dfd6aacfa691a2f7ccf7ce853acd6 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 3 Nov 2016 13:51:10 -0700 Subject: [PATCH] findleaves.py: prevent recursion into symlink loops Keep a set of all visited inodes, and prevent recursing into a symlink to an already visited inode. Test: m -j Test: compare `build/tools/findleaves.py --prune=.repo --prune=.git --mindepth=2 --dir=. Android.mk` before and after Change-Id: Ied14c40d3066ef9f8e8a2b1535f56f7bbbbd0ab6 --- tools/findleaves.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/findleaves.py b/tools/findleaves.py index 72cc02456..f152a87e7 100755 --- a/tools/findleaves.py +++ b/tools/findleaves.py @@ -26,6 +26,7 @@ import sys def perform_find(mindepth, prune, dirlist, filenames): result = [] pruneleaves = set(map(lambda x: os.path.split(x)[1], prune)) + seen = set() for rootdir in dirlist: rootdepth = rootdir.count("/") for root, dirs, files in os.walk(rootdir, followlinks=True): @@ -52,6 +53,18 @@ def perform_find(mindepth, prune, dirlist, filenames): if filename in files: result.append(os.path.join(root, filename)) del dirs[:] + + # filter out inodes that have already been seen due to symlink loops + i = 0 + while i < len(dirs): + st = os.stat(os.path.join(root, dirs[i])) + key = (st.st_dev, st.st_ino) + if key in seen: + del dirs[i] + else: + i += 1 + seen.add(key) + return result def usage():