[Git][reproducible-builds/diffoscope][master] 4 commits: Factor out the ability to ignore the exit codes of "zipinfo" and "zipinfo -v"...

Chris Lamb gitlab at salsa.debian.org
Mon Jul 29 14:08:36 UTC 2019



Chris Lamb pushed to branch master at Reproducible Builds / diffoscope


Commits:
a98f743a by Chris Lamb at 2019-07-29T13:50:32Z
Factor out the ability to ignore the exit codes of "zipinfo" and "zipinfo -v" in the presence of non-standard headers. (re. reproducible-builds/diffoscope#60)

- - - - -
f1b6924d by Chris Lamb at 2019-07-29T13:54:58Z
Only override the exit code from our special-cased calls to zipinfo(1) if they are 1 or 2 to avoid potentially masking real errors. (re. reproducible-builds/diffoscope#60)

- - - - -
595e643f by Chris Lamb at 2019-07-29T14:05:42Z
Add missing textual DESCRIPTIONs for ZipFile and MozillaZipFile.

- - - - -
4af81ba2 by Chris Lamb at 2019-07-29T14:05:42Z
Add support for Java ".jmod" modules. (Closes: reproducible-builds/diffoscope#60, Debian:#933308)

Thanks to Emmanuel Bourg (ebourg at apache.org) for the bug report.

Signed-off-by: Chris Lamb <lamby at debian.org>

- - - - -


6 changed files:

- diffoscope/comparators/__init__.py
- diffoscope/comparators/zip.py
- tests/comparators/test_zip.py
- + tests/data/jmod_zipinfo_expected_diff
- + tests/data/test1.jmod
- + tests/data/test2.jmod


Changes:

=====================================
diffoscope/comparators/__init__.py
=====================================
@@ -89,6 +89,7 @@ class ComparatorManager(object):
         ('docx.DocxFile',),
         ('zip.MozillaZipFile',),
         ('zip.ZipFile',),
+        ('zip.JmodJavaModule',),
         ('image.JPEGImageFile',),
         ('image.ICOImageFile',),
         ('cbfs.CbfsFile',),


=====================================
diffoscope/comparators/zip.py
=====================================
@@ -160,19 +160,23 @@ class ZipContainer(Archive):
 
 
 class ZipFile(File):
+    DESCRIPTION = 'ZIP archives'
     CONTAINER_CLASS = ZipContainer
     FILE_TYPE_RE = re.compile(
         r'^(Zip archive|Java archive|EPUB document|OpenDocument (Text|Spreadsheet|Presentation|Drawing|Formula|Template|Text Template)|Google Chrome extension)\b'
     )
 
+    ZIPINFO = Zipinfo
+    ZIPINFO_VERBOSE = ZipinfoVerbose
+
     def compare_details(self, other, source=None):
         differences = []
         zipinfo_difference = None
         if Config().exclude_directory_metadata != 'recursive':
             zipinfo_difference = (
-                Difference.from_command(Zipinfo, self.path, other.path)
+                Difference.from_command(self.ZIPINFO, self.path, other.path)
                 or Difference.from_command(
-                    ZipinfoVerbose, self.path, other.path
+                    self.ZIPINFO_VERBOSE, self.path, other.path
                 )
                 or Difference.from_command(
                     BsdtarVerbose, self.path, other.path
@@ -187,19 +191,25 @@ class ZipFile(File):
         return differences
 
 
-class MozillaZipCommandMixin(object):
+class IgnoreReturncodeMixin(object):
     @property
     def returncode(self):
-        # zipinfo emits an error when reading Mozilla-optimized ZIPs,
-        # which is fine to ignore.
-        return 0
+        returncode = super().returncode
+
+        # zipinfo returns with an exit code of 1 or 2 when reading
+        # Mozilla-optimized or Java "jmod" ZIPs as they have non-standard
+        # headers which are safe to ignore.
+        if returncode in (1, 2):
+            returncode = 0
+
+        return returncode
 
 
-class MozillaZipinfo(MozillaZipCommandMixin, Zipinfo):
+class IgnoreReturncodeZipinfo(IgnoreReturncodeMixin, Zipinfo):
     pass
 
 
-class MozillaZipinfoVerbose(MozillaZipCommandMixin, ZipinfoVerbose):
+class IgnoreReturncodeZipinfoVerbose(IgnoreReturncodeMixin, ZipinfoVerbose):
     pass
 
 
@@ -223,9 +233,13 @@ class MozillaZipContainer(ZipContainer):
         return result
 
 
-class MozillaZipFile(File):
+class MozillaZipFile(ZipFile):
+    DESCRIPTION = 'Mozilla-optimized .ZIP archives'
     CONTAINER_CLASS = MozillaZipContainer
 
+    ZIPINFO = IgnoreReturncodeZipinfo
+    ZIPINFO_VERBOSE = IgnoreReturncodeZipinfoVerbose
+
     @classmethod
     def recognizes(cls, file):
         # Mozilla-optimized ZIPs start with a 32-bit little endian integer
@@ -233,14 +247,10 @@ class MozillaZipFile(File):
         # central directory (with a PK\x01\x02 signature)
         return file.file_header[4:8] == b'PK\x01\x02'
 
-    def compare_details(self, other, source=None):
-        if Config().exclude_directory_metadata == 'recursive':
-            return []
-        zipinfo_difference = (
-            Difference.from_command(MozillaZipinfo, self.path, other.path)
-            or Difference.from_command(
-                MozillaZipinfoVerbose, self.path, other.path
-            )
-            or Difference.from_command(BsdtarVerbose, self.path, other.path)
-        )
-        return [zipinfo_difference]
+
+class JmodJavaModule(ZipFile):
+    DESCRIPTION = 'Java .jmod modules'
+    FILE_TYPE_RE = re.compile(r'^Java jmod module\b')
+
+    ZIPINFO = IgnoreReturncodeZipinfo
+    ZIPINFO_VERBOSE = IgnoreReturncodeZipinfoVerbose


=====================================
tests/comparators/test_zip.py
=====================================
@@ -19,7 +19,7 @@
 
 import pytest
 
-from diffoscope.comparators.zip import ZipFile, MozillaZipFile
+from diffoscope.comparators.zip import ZipFile, MozillaZipFile, JmodJavaModule
 
 from ..utils.data import load_fixture, get_data
 from ..utils.tools import skip_unless_tools_exist
@@ -33,6 +33,8 @@ encrypted_zip1 = load_fixture('encrypted1.zip')
 encrypted_zip2 = load_fixture('encrypted2.zip')
 mozzip1 = load_fixture('test1.mozzip')
 mozzip2 = load_fixture('test2.mozzip')
+jmod1 = load_fixture('test1.jmod')
+jmod2 = load_fixture('test2.jmod')
 test_comment1 = load_fixture('test_comment1.zip')
 test_comment2 = load_fixture('test_comment2.zip')
 
@@ -119,6 +121,27 @@ def test_mozzip_compare_non_existing(monkeypatch, mozzip1):
     assert_non_existing(monkeypatch, mozzip1)
 
 
+def test_jmod_identification(jmod1):
+    assert isinstance(jmod1, JmodJavaModule)
+
+
+def test_jmod_no_differences(jmod1):
+    difference = jmod1.compare(jmod1)
+    assert difference is None
+
+
+ at pytest.fixture
+def jmod_differences(jmod1, jmod2):
+    return jmod1.compare(jmod2).details
+
+
+ at skip_unless_tools_exist('zipinfo')
+def test_jmod_metadata(jmod_differences, jmod1, jmod2):
+    expected_diff = get_data('jmod_zipinfo_expected_diff')
+    diff = jmod_differences[0].unified_diff
+    assert jmod_differences[0].unified_diff == expected_diff
+
+
 def test_encrypted(encrypted_zip1, encrypted_zip2):
     difference = encrypted_zip1.compare(encrypted_zip2)
     assert difference is not None


=====================================
tests/data/jmod_zipinfo_expected_diff
=====================================
@@ -0,0 +1,15 @@
+@@ -1,8 +1,11 @@
+-Zip file size: 9857 bytes, number of entries: 4
++Zip file size: 11672 bytes, number of entries: 7
+ warning [/dev/stdin]:  4 extra bytes at beginning or within zipfile
+   (attempting to process anyway)
+--rw----     2.0 fat      680 bl defN 19-Jul-17 04:54 classes/module-info.class
++-rw----     2.0 fat      263 bl defN 19-Jul-17 04:54 classes/module-info.class
++-rw----     2.0 fat      292 bl defN 19-Jul-17 04:54 classes/javax/transaction/xa/Xid.class
++-rw----     2.0 fat     1062 bl defN 19-Jul-17 04:54 classes/javax/transaction/xa/XAResource.class
++-rw----     2.0 fat     1497 bl defN 19-Jul-17 04:54 classes/javax/transaction/xa/XAException.class
+ -rw----     2.0 fat     2114 bl defN 19-Jul-17 04:54 legal/ADDITIONAL_LICENSE_INFO
+ -rw----     2.0 fat     1522 bl defN 19-Jul-17 04:54 legal/ASSEMBLY_EXCEPTION
+ -rw----     2.0 fat    19274 bl defN 19-Jul-17 04:54 legal/LICENSE
+-4 files, 23590 bytes uncompressed, 9281 bytes compressed:  60.7%
++7 files, 26024 bytes uncompressed, 10562 bytes compressed:  59.4%


=====================================
tests/data/test1.jmod
=====================================
Binary files /dev/null and b/tests/data/test1.jmod differ


=====================================
tests/data/test2.jmod
=====================================
Binary files /dev/null and b/tests/data/test2.jmod differ



View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/compare/efd5f9591226138075d4a2921c2b4ed8e761910c...4af81ba2e083568c2a255677c7bedaec9892c85d

-- 
View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/compare/efd5f9591226138075d4a2921c2b4ed8e761910c...4af81ba2e083568c2a255677c7bedaec9892c85d
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.reproducible-builds.org/pipermail/rb-commits/attachments/20190729/a5a1c58c/attachment.html>


More information about the rb-commits mailing list