<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>