<div dir="ltr">If an ELF file specifies a list of RPATHs, for each shared library<br>dependency search each RPATH and see if the package contains it in that<br>location.<br><br><a href="https://bugs.archlinux.org/task/43239?string=namcap&project=1&type[0]=&sev[0]=&pri[0]=&due[0]=&reported[0]=&cat[0]=&status[0]=open&percent[0]=&opened=&dev=&closed=&duedatefrom=&duedateto=&changedfrom=&changedto=&openedfrom=&openedto=&closedfrom=&closedto=">FS#43239</a><br><br>Signed-off-by: Nicola Squartini <<a href="mailto:tensor5@gmail.com">tensor5@gmail.com</a>><br>---<br>Â Namcap/rules/sodepends.py | 33 ++++++++++++++++++++++++---------<br>Â 1 file changed, 24 insertions(+), 9 deletions(-)<br><br>diff --git a/Namcap/rules/sodepends.py b/Namcap/rules/sodepends.py<br>index 92826af..527f511 100644<br>--- a/Namcap/rules/sodepends.py<br>+++ b/Namcap/rules/sodepends.py<br>@@ -28,6 +28,7 @@ import subprocess<br>Â import tempfile<br>Â import Namcap.package<br>Â from Namcap.ruleclass import *<br>+from Namcap.rules.rpath import get_rpaths<br>Â <br>Â libcache = {'i686': {}, 'x86-64': {}}<br>Â <br>@@ -43,7 +44,7 @@ def figurebitsize(line):<br>Â Â Â Â else:<br>Â Â Â Â Â Â Â return 'i686'<br>Â <br>-def scanlibs(fileobj, filename, sharedlibs):<br>+def scanlibs(fileobj, filename, sharedlibs, tarlist):<br>Â Â Â Â """<br>Â Â Â Â Run "readelf -d" on a file-like object (e.g. a TarFile)<br>Â <br>@@ -52,6 +53,7 @@ def scanlibs(fileobj, filename, sharedlibs):<br>Â Â Â Â sharedlibs: a dictionary { library => set(ELF files using that library) }<br>Â Â Â Â """<br>Â Â Â Â shared = re.compile('Shared library: \[(.*)\]')<br>+Â Â Â origin = re.compile('^\$ORIGIN|^\$\{ORIGIN\}')<br>Â <br>Â Â Â Â # test magic bytes<br>Â Â Â Â magic = fileobj.read(4)<br>@@ -71,18 +73,31 @@ def scanlibs(fileobj, filename, sharedlibs):<br>Â Â Â Â Â Â Â var = p.communicate()<br>Â Â Â Â Â Â Â assert(p.returncode == 0)<br>Â Â Â Â Â Â Â for j in var[0].decode('ascii').splitlines():<br>+Â Â Â Â Â Â Â Â Â found = False<br>Â Â Â Â Â Â Â Â Â Â n = shared.search(j)<br>Â Â Â Â Â Â Â Â Â Â # Is this a Shared library: line?<br>Â Â Â Â Â Â Â Â Â Â if n != None:<br>Â Â Â Â Â Â Â Â Â Â Â Â Â # Find out its architecture<br>Â Â Â Â Â Â Â Â Â Â Â Â Â architecture = figurebitsize(j)<br>-Â Â Â Â Â Â Â Â Â Â Â Â try:<br>-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â libpath = os.path.abspath(<br>-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â libcache[architecture][n.group(1)])[1:]<br>-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â sharedlibs.setdefault(libpath, set()).add(filename)<br>-Â Â Â Â Â Â Â Â Â Â Â Â except KeyError:<br>-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â # We didn't know about the library, so add it for fail later<br>-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â sharedlibs.setdefault(n.group(1), set()).add(filename)<br>+Â Â Â Â Â Â Â Â Â Â Â Â # If file has RPATH, check if shared library is already packaged<br>+Â Â Â Â Â Â Â Â Â Â Â Â for rpath in get_rpaths(<a href="http://tmp.name">tmp.name</a>):<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â # Expand $ORIGIN<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â realrpath = origin.sub(os.path.dirname(filename), rpath)<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â libpath = os.path.normpath(os.path.join(realrpath, n.group(1)))<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â # Remove possible leading '/'<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â libpath = re.sub('^/', '', libpath)<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â if libpath in tarlist:<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â sharedlibs.setdefault(libpath, set()).add(filename)<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â found = True<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â break<br>+Â Â Â Â Â Â Â Â Â Â Â Â if not found:<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â try:<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â libpath = os.path.abspath(<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â libcache[architecture][n.group(1)])[1:]<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â sharedlibs.setdefault(libpath, set()).add(filename)<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â except KeyError:<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â # We didn't know about the library, so add it for fail later<br>+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â sharedlibs.setdefault(n.group(1), set()).add(filename)<br>Â Â Â Â finally:<br>Â Â Â Â Â Â Â os.unlink(<a href="http://tmp.name">tmp.name</a>)<br>Â <br>@@ -157,7 +172,7 @@ class SharedLibsRule(TarballRule):<br>Â Â Â Â Â Â Â Â Â Â if not entry.isfile():<br>Â Â Â Â Â Â Â Â Â Â Â Â Â continue<br>Â Â Â Â Â Â Â Â Â Â f = tar.extractfile(entry)<br>-Â Â Â Â Â Â Â Â Â scanlibs(f, <a href="http://entry.name">entry.name</a>, liblist)<br>+Â Â Â Â Â Â Â Â Â scanlibs(f, <a href="http://entry.name">entry.name</a>, liblist, tar.getnames())<br>Â Â Â Â Â Â Â Â Â Â f.close()<br>Â <br>Â Â Â Â Â Â Â # Ldd all the files and find all the link and script dependencies<br>-- <br>2.8.2<br><br><br></div>