[arch-projects] [namcap][PATCH] Add a test for overlinking (unused shared libraries)

Jan Alexander Steffens (heftig) jan.steffens at gmail.com
Sat Nov 2 17:17:49 EDT 2013


Based on the rpath code.
---
 Namcap/rules/__init__.py                     |  3 +-
 Namcap/rules/unusedsodepends.py              | 76 ++++++++++++++++++++++++++++
 Namcap/tests/package/test_unusedsodepends.py | 66 ++++++++++++++++++++++++
 namcap-tags                                  |  1 +
 4 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 Namcap/rules/unusedsodepends.py
 create mode 100644 Namcap/tests/package/test_unusedsodepends.py

diff --git a/Namcap/rules/__init__.py b/Namcap/rules/__init__.py
index f7780d2..a1b6775 100644
--- a/Namcap/rules/__init__.py
+++ b/Namcap/rules/__init__.py
@@ -46,7 +46,8 @@ from . import (
   scrollkeeper,
   shebangdepends,
   sodepends,
-  symlink
+  symlink,
+  unusedsodepends
 )
 
 # PKGBUILD and metadata rules
diff --git a/Namcap/rules/unusedsodepends.py b/Namcap/rules/unusedsodepends.py
new file mode 100644
index 0000000..4d6a5be
--- /dev/null
+++ b/Namcap/rules/unusedsodepends.py
@@ -0,0 +1,76 @@
+#
+# namcap rules - unusedsodepends
+# Copyright (C) 2009 Abhishek Dasgupta <abhidg at gmail.com>
+# Copyright (C) 2013 Jan Alexander Steffens <jan.steffens at gmail.com>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+import os, subprocess, re
+import tempfile
+from Namcap.util import is_elf, clean_filename
+from Namcap.ruleclass import *
+
+libre = re.compile('^\t(/.*)')
+lddfail = re.compile('^\tnot a dynamic executable')
+
+def get_unused_sodepends(filename):
+	p = subprocess.Popen(["ldd", "-r", "-u", filename],
+		env={'LANG': 'C'},
+		stdout=subprocess.PIPE,
+		stderr=subprocess.PIPE)
+	var = p.communicate()
+	if p.returncode == 0:
+		return
+	else:
+		for j in var[0].decode('ascii').splitlines():
+			# Don't raise an error, as the executable might be a valid ELF file,
+			# just not a dynamically linked one
+			n = lddfail.search(j)
+			if n is not None:
+				return
+
+			n = libre.search(j)
+			if n is not None:
+				yield n.group(1)
+
+class package(TarballRule):
+	name = "unusedsodepends"
+	description = "Checks for unused dependencies caused by linked shared libraries"
+	def analyze(self, pkginfo, tar):
+		for entry in tar:
+			if not entry.isfile():
+				continue
+
+			# is it an ELF file ?
+			f = tar.extractfile(entry)
+			elf = f.read()
+			f.close()
+			if elf[:4] != b"\x7fELF":
+				continue # not an ELF file
+
+			# write it to a temporary file
+			f = tempfile.NamedTemporaryFile(delete = False)
+			f.write(elf)
+			f.close()
+
+			os.chmod(f.name, 0o755)
+
+			for lib in get_unused_sodepends(f.name):
+				self.warnings.append(("unused-sodepend %s %s", (lib, entry.name)))
+
+			os.unlink(f.name)
+
+# vim: set ts=4 sw=4 noet:
diff --git a/Namcap/tests/package/test_unusedsodepends.py b/Namcap/tests/package/test_unusedsodepends.py
new file mode 100644
index 0000000..b2002f7
--- /dev/null
+++ b/Namcap/tests/package/test_unusedsodepends.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+#
+# namcap tests - unusedsodepends
+# Copyright (C) 2011 Rémy Oudompheng <remy at archlinux.org>
+# Copyright (C) 2013 Jan Alexander Steffens <jan.steffens at gmail.com>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+#   USA
+#
+
+import os
+from Namcap.tests.makepkg import MakepkgTest
+import Namcap.rules.unusedsodepends
+
+class UnusedSodependsTest(MakepkgTest):
+	pkgbuild = """
+pkgname=__namcap_test_unusedsodepends
+pkgver=1.0
+pkgrel=1
+pkgdesc="A package"
+arch=('i686' 'x86_64')
+url="http://www.example.com/"
+license=('GPL')
+depends=('glibc')
+source=()
+options=(!purge !zipman)
+build() {
+  cd "${srcdir}"
+  echo "int main() { return 0; }" > main.c
+  /usr/bin/gcc -o main main.c -lm
+}
+package() {
+  install -D -m 755 "$srcdir/main" "$pkgdir/usr/bin/evilprogram"
+}
+"""
+	def test_unusedsodepends_files(self):
+		"Package with binaries linking to unused shared libraries"
+		pkgfile = "__namcap_test_unusedsodepends-1.0-1-%(arch)s.pkg.tar" % { "arch": self.arch }
+		with open(os.path.join(self.tmpdir, "PKGBUILD"), "w") as f:
+			f.write(self.pkgbuild)
+		self.run_makepkg()
+		pkg, r = self.run_rule_on_tarball(
+				os.path.join(self.tmpdir, pkgfile),
+				Namcap.rules.unusedsodepends.package
+				)
+		self.assertEqual(r.errors, [])
+		self.assertEqual(r.warnings, [
+			("unused-sodepend %s %s",
+			("/usr/lib/libm.so.6", "usr/bin/evilprogram"))
+		])
+		self.assertEqual(r.infos, [])
+
+# vim: set ts=4 sw=4 noet:
+
diff --git a/namcap-tags b/namcap-tags
index d638478..e5656f4 100644
--- a/namcap-tags
+++ b/namcap-tags
@@ -74,6 +74,7 @@ specific-host-type-used %s :: Reference to %s should be changed to $CARCH
 specific-sourceforge-mirror :: Attempting to use specific sourceforge mirror, use downloads.sourceforge.net instead
 symlink-found %s points to %s :: Symlink (%s) found that points to %s
 too-many-checksums %s %i needed :: Too many %s: %i needed
+unused-sodepend %s %s :: Unused shared library '%s' by file ('%s')
 use-pkgdir :: Use $pkgdir instead of $startdir/pkg
 use-srcdir :: Use $srcdir instead of $startdir/src
 using-dl-sourceforge :: Attempting to use dl sourceforge domain, use downloads.sourceforge.net instead
-- 
1.8.4.2



More information about the arch-projects mailing list