[Piuparts-devel] Bug#648784: [PATCH 2/2] fix symlink resolution inside paths
Andreas Beckmann
debian at abeckmann.de
Wed Nov 16 03:24:34 UTC 2011
is_broken_symlink() fails to properly resolve e.g.
$ROOT/etc/motd -> /var/run/motd
$ROOT/var/run -> /run
and reports a broken link even if $ROOT/run/motd exists.
Adds a canonicalize_path() method that does not only look for
symlinks at the end of the path but also as intermediate parts.
(does not properly handle /../, /./, //)
This should fix about 30000 incorrect warnings on piatti.
Signed-off-by: Andreas Beckmann <debian at abeckmann.de>
---
debian/changelog | 7 +++++++
piuparts.py | 21 ++++++++++++++++++---
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 7842e04..52cd242 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -27,6 +27,13 @@ piuparts (0.42) UNRELEASED; urgency=low
- Replace deprecated os.popen2 with subprocess.Popen. (Closes: #640646)
- add some more logging.
+ [ Andreas Beckmann ]
+ * piuparts.py:
+ - Fix resolving absolute symlinks of intermediate directory components,
+ i.e. /var/run -> /run while checking /etc/motd -> /var/run/motd.
+ Solves about 30000 false positives of
+ 'Broken symlinks: /etc/motd -> /var/run/motd'. (Closes: #648784)
+
-- Holger Levsen <holger at debian.org> Sun, 28 Aug 2011 09:50:12 +0200
piuparts (0.41) unstable; urgency=low
diff --git a/piuparts.py b/piuparts.py
index 5f015fe..1de475b 100644
--- a/piuparts.py
+++ b/piuparts.py
@@ -474,8 +474,8 @@ def make_metapackage(name, depends, conflicts):
return os.path.join(tmpdir, name) + '.deb'
-def is_broken_symlink(root, dirpath, filename):
- """Is symlink dirpath+filename broken?
+def canonicalize_path(root, pathname):
+ """Canonicalize a path name, simulating chroot at 'root'.
When resolving the symlink, pretend (similar to chroot) that root is
the root of the filesystem. Note that this does NOT work completely
@@ -486,17 +486,32 @@ def is_broken_symlink(root, dirpath, filename):
"""
- pathname = os.path.join(dirpath, filename)
+ #print "CANONICALIZE: %s %s" % (root, pathname)
i = 0
while os.path.islink(pathname):
if i >= 10: # let's avoid infinite loops...
return True
i += 1
target = os.readlink(pathname)
+ #print "LINK: %s -> %s" % (pathname, target)
if os.path.isabs(target):
pathname = os.path.join(root, target[1:]) # Assume Unix filenames
else:
pathname = os.path.join(os.path.dirname(pathname), target)
+ #print "FOLLOW: %s" % pathname
+ (dn, bn) = os.path.split(pathname)
+ #print "DN: %s BN: %s" % (dn, bn)
+ if pathname != root and dn != root:
+ dn = canonicalize_path(root, dn)
+ pathname = os.path.join(dn, bn)
+ #print "RETURN: %s EXISTS: %s" % (pathname, os.path.exists(pathname))
+ return pathname
+
+
+def is_broken_symlink(root, dirpath, filename):
+ """Is symlink dirpath+filename broken?"""
+
+ pathname = canonicalize_path(root, os.path.join(dirpath, filename))
# The symlink chain, if any, has now been resolved. Does the target
# exist?
--
1.7.7.1
More information about the Piuparts-devel
mailing list