[diffoscope] 01/02: Use Ar container comparison when ElfContainer is not applicable.

Maria Glukhova siamezzze-guest at moszumanska.debian.org
Sun Feb 26 04:50:01 CET 2017


This is an automated email from the git hooks/post-receive script.

siamezzze-guest pushed a commit to branch siamezzze/elf
in repository diffoscope.

commit 6e4cf15dfb6966e2da41afe43bd502de6b128423
Author: Maria Glukhova <siamezzze at gmail.com>
Date:   Fri Feb 3 02:13:16 2017 +0200

    Use Ar container comparison when ElfContainer is not applicable.
    
    Files with .a extension and "ar archive" in file type description
    are treated as SharedLibrary and compared using readelf/objdump.
    However, if the archive does not contain elf object files,
    that approach will result in error from readelf (re. #849407).
    
    It would be better to check if the .a file actually
    contain elf files and if not, fall back to regular Ar-files
    comparison. That should also help in case readelf/objdump is not
    available.
---
 diffoscope/comparators/elf.py        | 20 +++++++++++--
 tests/comparators/test_ar.py         | 57 ++++++++++++++++++++++++++++++++++++
 tests/data/ar_content_expected_diff  |  3 ++
 tests/data/ar_filelist_expected_diff |  3 ++
 tests/data/test3.a                   |  4 +++
 tests/data/test4.a                   |  3 ++
 6 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/diffoscope/comparators/elf.py b/diffoscope/comparators/elf.py
index 17b0f26..e6cc533 100644
--- a/diffoscope/comparators/elf.py
+++ b/diffoscope/comparators/elf.py
@@ -539,11 +539,27 @@ class StaticLibFile(File):
     CONTAINER_CLASS = ElfContainer
     RE_FILE_TYPE = re.compile(r'\bar archive\b')
     RE_FILE_EXTENSION = re.compile(r'\.a$')
+    RE_AR_MEMBER_TYPE = re.compile(r'\bfile format elf.*\b')
 
     @staticmethod
     def recognizes(file):
-        return StaticLibFile.RE_FILE_TYPE.search(file.magic_file_type) and \
-            StaticLibFile.RE_FILE_EXTENSION.search(file.name)
+        if not (StaticLibFile.RE_FILE_TYPE.search(file.magic_file_type) and
+                StaticLibFile.RE_FILE_EXTENSION.search(file.name)):
+            return False
+        try:
+            logger.debug("Checking if %s contain elf files", file.path)
+            output = subprocess.check_output(['objdump', '-a', file.path],
+                                             shell=False,
+                                             stderr=subprocess.DEVNULL)
+            file_list = output.decode('utf-8', errors='ignore')
+            file_formats = StaticLibFile.RE_AR_MEMBER_TYPE.findall(file_list)
+            if len(file_formats) == 0:
+                return False
+        except (subprocess.CalledProcessError, OSError):
+            logger.debug("Unable to check contents of %s using objdump",
+                         file.path)
+            return False
+        return True
 
     def compare_details(self, other, source=None):
         differences = [Difference.from_text_readers(
diff --git a/tests/comparators/test_ar.py b/tests/comparators/test_ar.py
new file mode 100644
index 0000000..abaa45d
--- /dev/null
+++ b/tests/comparators/test_ar.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+#
+# diffoscope: in-depth comparison of files, archives, and directories
+#
+# Copyright © 2017 Maria Glukhova <siammezzze at gmail.com>
+#
+# diffoscope 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 3 of the License, or
+# (at your option) any later version.
+#
+# diffoscope 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 diffoscope.  If not, see <https://www.gnu.org/licenses/>.
+
+import pytest
+
+from diffoscope.comparators.ar import ArFile
+
+from utils.data import load_fixture, get_data
+from utils.tools import skip_unless_tools_exist
+from utils.nonexisting import assert_non_existing
+
+ar1 = load_fixture('test3.a')
+ar2 = load_fixture('test4.a')
+
+def test_identification(ar1):
+    assert isinstance(ar1, ArFile)
+
+def test_no_differences(ar1):
+    difference = ar1.compare(ar1)
+    assert difference is None
+
+ at pytest.fixture
+def differences(ar1, ar2):
+    return ar1.compare(ar2).details
+
+def test_compare_non_existing(monkeypatch, ar1):
+    assert_non_existing(monkeypatch, ar1)
+
+ at skip_unless_tools_exist('nm')
+def test_filelist(differences):
+    assert differences[0].source1 == 'file list'
+    assert differences[0].source2 == 'file list'
+    expected_diff = get_data('ar_filelist_expected_diff')
+    assert differences[0].unified_diff == expected_diff
+
+ at skip_unless_tools_exist('nm')
+def test_content(differences):
+    assert differences[1].source1 == 'a.txt'
+    assert differences[1].source2 == 'a.txt'
+    expected_diff = get_data('ar_content_expected_diff')
+    assert differences[1].unified_diff == expected_diff
diff --git a/tests/data/ar_content_expected_diff b/tests/data/ar_content_expected_diff
new file mode 100644
index 0000000..c696e6b
--- /dev/null
+++ b/tests/data/ar_content_expected_diff
@@ -0,0 +1,3 @@
+@@ -1 +1 @@
+-Test
++Test!
diff --git a/tests/data/ar_filelist_expected_diff b/tests/data/ar_filelist_expected_diff
new file mode 100644
index 0000000..fd15a75
--- /dev/null
+++ b/tests/data/ar_filelist_expected_diff
@@ -0,0 +1,3 @@
+@@ -1 +1 @@
+-?rw-r--r--   0        0        0        5 1970-01-01 00:00:00.000000 a.txt
++?rw-r--r--   0        0        0        6 1970-01-01 00:00:00.000000 a.txt
diff --git a/tests/data/test3.a b/tests/data/test3.a
new file mode 100644
index 0000000..6b2b3f6
--- /dev/null
+++ b/tests/data/test3.a
@@ -0,0 +1,4 @@
+!<arch>
+a.txt/          0           0     0     644     5         `
+Test
+
diff --git a/tests/data/test4.a b/tests/data/test4.a
new file mode 100644
index 0000000..acb400d
--- /dev/null
+++ b/tests/data/test4.a
@@ -0,0 +1,3 @@
+!<arch>
+a.txt/          0           0     0     644     6         `
+Test!

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list