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