summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Keen <keenerd@gmail.com>2016-06-18 09:10:36 -0400
committerKyle Keen <keenerd@gmail.com>2016-06-18 09:10:36 -0400
commitf406eb9751070bf2186e693382d1170eaace962b (patch)
tree7259350fe7cbe737d7c97703c914f1bf432b5970
parentf8850453ef59305bba13b3c6e492a9e4ce00720e (diff)
downloadnamcap-f406eb9751070bf2186e693382d1170eaace962b.tar.gz
namcap-f406eb9751070bf2186e693382d1170eaace962b.zip
Stricter shebang parsing (FS#49733)
Also adds a test case for shebangdepends. Signed-off-by: Kyle Keen <keenerd@gmail.com>
-rw-r--r--Namcap/rules/shebangdepends.py2
-rw-r--r--Namcap/tests/package/test_shebangdepends.py64
-rw-r--r--Namcap/util.py5
3 files changed, 68 insertions, 3 deletions
diff --git a/Namcap/rules/shebangdepends.py b/Namcap/rules/shebangdepends.py
index 1af9139..bac153f 100644
--- a/Namcap/rules/shebangdepends.py
+++ b/Namcap/rules/shebangdepends.py
@@ -37,7 +37,6 @@ def scanshebangs(fileobj, filename, scripts):
Stores
scripts -- a dictionary { program => set(scripts) }
"""
- # todo: this function has no test coverage
# test magic bytes
magic = fileobj.read(2)
@@ -64,7 +63,6 @@ def findowners(scriptlist):
pkglist -- a dictionary { package => set(programs) }
orphans -- a set of scripts not found
"""
- # todo: this function has no test coverage
pkglist = {}
scriptfound = set()
diff --git a/Namcap/tests/package/test_shebangdepends.py b/Namcap/tests/package/test_shebangdepends.py
new file mode 100644
index 0000000..dbacd86
--- /dev/null
+++ b/Namcap/tests/package/test_shebangdepends.py
@@ -0,0 +1,64 @@
+# namcap tests - shebangdepends
+# Copyright (C) 2016 Kyle Keen <keenerd@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.shebangdepends
+
+class ShebangDependsTest(MakepkgTest):
+ pkgbuild = """
+pkgname=__namcap_test_shebangdepends
+pkgver=1.0
+pkgrel=1
+pkgdesc="A package"
+arch=('any')
+url="http://www.example.com/"
+license=('GPL')
+depends=()
+source=()
+options=(!purge !zipman)
+build() {
+ cd "${srcdir}"
+ echo -e "#! /usr/bin/env python\nprint('a script')" > python_sample
+ echo -e "#!/bin\\xffary/da\\x00ta\ncrash?" > binary_sample
+}
+package() {
+ install -Dm755 "$srcdir/python_sample" "$pkgdir/usr/bin/python_sample"
+ install -Dm755 "$srcdir/binary_sample" "$pkgdir/usr/share/binary_sample"
+}
+"""
+ def test_shebangdepends(self):
+ "Package with missing python dependency"
+ pkgfile = "__namcap_test_shebangdepends-1.0-1-any.pkg.tar"
+ 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.shebangdepends.ShebangDependsRule
+ )
+ e, w, i = Namcap.depends.analyze_depends(pkg)
+ self.assertEqual(e, [
+ ('dependency-detected-not-included %s (%s)',
+ ('python', "programs ['python'] needed in scripts ['usr/bin/python_sample']"))
+ ])
+ self.assertEqual(w, [])
+
+# vim: set ts=4 sw=4 noet:
+
diff --git a/Namcap/util.py b/Namcap/util.py
index a28784d..1b47f64 100644
--- a/Namcap/util.py
+++ b/Namcap/util.py
@@ -59,7 +59,10 @@ def is_elf(path):
def script_type(path):
firstline = _read_carefully(path, lambda fd: fd.readline())
- firstline = firstline.decode('ascii', 'ignore')
+ try:
+ firstline = firstline.decode('utf-8', 'strict')
+ except UnicodeDecodeError:
+ return None
if not firstline:
return None
script = re.compile('#!.*/(.*)')