[namcap,5/5] Fix shebangdepends rule for programs found in noncanonical locations

Message ID 20200117131931.1746498-5-archlinux@thecybershadow.net
State New
Headers show
Series [namcap,1/5] namcap-devel: Quote arguments | expand

Commit Message

Vladimir Panteleev Jan. 17, 2020, 1:19 p.m. UTC
If the user has a non-canonical (i.e. symlinked on Arch) location in
front of their $PATH, such as /usr/sbin, shutil.which will return
locations with that path. This later causes the rule to fail to find
the binary in any packages, causing spurious
library-no-package-associated and dependency-not-needed warnings.

Fix this by resolving all symlinks for executables (using
os.path.realpath) before trying to find them among installed packages.
---
 Namcap/rules/shebangdepends.py              |  3 +-
 Namcap/tests/package/test_shebangdepends.py | 38 +++++++++++++++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

Comments

Emil Velikov via arch-projects Jan. 19, 2020, 12:42 a.m. UTC | #1
On 1/17/20 8:19 AM, Vladimir Panteleev wrote:
> If the user has a non-canonical (i.e. symlinked on Arch) location in
> front of their $PATH, such as /usr/sbin, shutil.which will return
> locations with that path. This later causes the rule to fail to find
> the binary in any packages, causing spurious
> library-no-package-associated and dependency-not-needed warnings.
> 
> Fix this by resolving all symlinks for executables (using
> os.path.realpath) before trying to find them among installed packages.

FWIW a lot of software will break if you do this, not just namcap.
There's an exceedingly good reason why /usr/sbin and other symlink
directories are *not* added to the $PATH on archlinux, unless the user
has unwisely added it by hand.
Vladimir Panteleev Jan. 21, 2020, 1:08 p.m. UTC | #2
Eli Schwartz <eschwartz@archlinux.org> writes:

> FWIW a lot of software will break if you do this, not just namcap.
> There's an exceedingly good reason why /usr/sbin and other symlink
> directories are *not* added to the $PATH on archlinux, unless the user
> has unwisely added it by hand.

FWIW, in my case I added it to my .profile so that it worked on other
distributions too, without requiring fancy logic such as checking distro
or filesystem layout. That was several years ago, and this is the first
problem I noticed so far.

Patch

diff --git a/Namcap/rules/shebangdepends.py b/Namcap/rules/shebangdepends.py
index 07896df..fc359c3 100644
--- a/Namcap/rules/shebangdepends.py
+++ b/Namcap/rules/shebangdepends.py
@@ -21,7 +21,7 @@ 
 
 """Checks dependencies on programs specified in shebangs."""
 
-import shutil
+import shutil, os.path
 import Namcap.package
 from Namcap.util import is_script, script_type
 from Namcap.ruleclass import *
@@ -59,6 +59,7 @@  def findowners(scriptlist):
 		out = shutil.which(s)
 		if not out:
 			continue
+		out = os.path.realpath(out)
 
 		# strip leading slash
 		scriptpath = out.lstrip('/')
diff --git a/Namcap/tests/package/test_shebangdepends.py b/Namcap/tests/package/test_shebangdepends.py
index dbacd86..b92e9fe 100644
--- a/Namcap/tests/package/test_shebangdepends.py
+++ b/Namcap/tests/package/test_shebangdepends.py
@@ -60,5 +60,43 @@  package() {
 		])
 		self.assertEqual(w, [])
 
+	valid_pkgbuild = """
+pkgname=__namcap_test_shebangdepends
+pkgver=1.0
+pkgrel=1
+pkgdesc="A package"
+arch=('any')
+url="http://www.example.com/"
+license=('GPL')
+depends=('python')
+source=()
+options=(!purge !zipman)
+build() {
+  cd "${srcdir}"
+  echo -e "#! /usr/bin/env python\nprint('a script')" > python_sample
+}
+package() {
+  install -Dm755 "$srcdir/python_sample" "$pkgdir/usr/bin/python_sample"
+}
+"""
+	def test_shebangdepends_noncanonical(self):
+		"shutil.which returns noncanonical path (e.g. in /usr/sbin)"
+		pkgfile = "__namcap_test_shebangdepends-1.0-1-any.pkg.tar"
+		with open(os.path.join(self.tmpdir, "PKGBUILD"), "w") as f:
+			f.write(self.valid_pkgbuild)
+		self.run_makepkg()
+		old_path = os.environ['PATH']
+		try:
+			os.environ['PATH'] = '/usr/sbin:' + old_path
+			pkg, r = self.run_rule_on_tarball(
+					os.path.join(self.tmpdir, pkgfile),
+					Namcap.rules.shebangdepends.ShebangDependsRule
+					)
+		finally:
+			os.environ['PATH'] = old_path
+		e, w, i = Namcap.depends.analyze_depends(pkg)
+		self.assertEqual(e, [])
+		self.assertEqual(w, [])
+
 # vim: set ts=4 sw=4 noet: