[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