[Git][reproducible-builds/diffoscope][master] Add support for dexdump. (Closes: reproducible-builds/diffoscope#134)

Chris Lamb (@lamby) gitlab at salsa.debian.org
Fri Feb 10 18:00:42 UTC 2023



Chris Lamb pushed to branch master at Reproducible Builds / diffoscope


Commits:
1bb9b812 by FC Stegerman at 2023-02-10T10:00:00-08:00
Add support for dexdump. (Closes: reproducible-builds/diffoscope#134)

- - - - -


6 changed files:

- debian/control
- diffoscope/comparators/dex.py
- diffoscope/external_tools.py
- tests/comparators/test_dex.py
- tests/data/dex_expected_diffs
- tests/data/dex_javap_14_expected_diffs


Changes:

=====================================
debian/control
=====================================
@@ -22,6 +22,7 @@ Build-Depends:
  debhelper-compat (= 13),
  default-jdk-headless <!nocheck> | default-jdk <!nocheck>,
  device-tree-compiler (>= 1.4.2) <!nocheck>,
+ dexdump <!nocheck>,
  dh-python (>= 2.20160818~),
  docx2txt <!nocheck>,
  dpkg-dev (>= 1.17.14),


=====================================
diffoscope/comparators/dex.py
=====================================
@@ -22,10 +22,12 @@ import os.path
 import logging
 import subprocess
 
-from diffoscope.tools import tool_required
+from diffoscope.difference import Difference
+from diffoscope.tools import tool_required, tool_check_installed
 
 from .utils.file import File
 from .utils.archive import Archive
+from .utils.command import Command
 
 logger = logging.getLogger(__name__)
 
@@ -61,3 +63,43 @@ class DexFile(File):
     FILE_TYPE_RE = re.compile(r"^Dalvik dex file .*\b")
     FILE_EXTENSION_SUFFIX = {".dex"}
     CONTAINER_CLASSES = [DexContainer]
+
+    def compare_details(self, other, source=None):
+        if tool_check_installed("dexdump"):
+            dexdump = Difference.from_operation(Dexdump, self.path, other.path)
+            if dexdump is not None:
+                dexdump.add_comment(
+                    "Ignoring differences in offsets to keep diff size reasonable."
+                )
+                return [dexdump]
+        else:
+            self.add_comment(
+                "'dexdump' command not installed; cannot compare format-specific details."
+            )
+        return []
+
+
+class Dexdump(Command):
+    @tool_required("dexdump")
+    def cmdline(self):
+        # -a : display annotations
+        # -d : disassemble code sections
+        # -f : display summary information from file header
+        # -h : display file header details
+        return ["dexdump", "-a", "-d", "-f", "-h", self.path]
+
+    def filter(self, line):
+        # Processing 'classes.dex'...
+        if line.startswith(b"Processing "):
+            return b""
+
+        # Opened 'classes.dex', DEX version '037'
+        if line.startswith(b"Opened "):
+            return line.split(b", ", 1)[-1]
+
+        # ignore differences in offsets
+        offsets = (b"annotations", b"class_data", b"interfaces")
+        if any(line.startswith(o + b"_off") for o in offsets):
+            return b""
+
+        return line


=====================================
diffoscope/external_tools.py
=====================================
@@ -52,6 +52,7 @@ EXTERNAL_TOOLS = {
         "guix": "imagemagick",
     },
     "cpio": {"debian": "cpio", "arch": "cpio", "guix": "cpio"},
+    "dexdump": {"debian": "dexdump"},
     "diff": {"debian": "diffutils", "arch": "diffutils", "guix": "diffutils"},
     "docx2txt": {"debian": "docx2txt", "arch": "docx2txt", "guix": "docx2txt"},
     "dumpimage": {


=====================================
tests/comparators/test_dex.py
=====================================
@@ -68,19 +68,25 @@ def differences(dex1, dex2):
 
 
 def check_dex_differences(differences, expected_diff):
-    assert differences[0].source1 == "test1.jar"
-    assert differences[0].source2 == "test2.jar"
-    zipinfo = differences[0].details[0]
-    classdiff = differences[0].details[1]
+    assert differences[0].source1 == "dexdump -a -d -f -h {}"
+    assert differences[0].source2 == "dexdump -a -d -f -h {}"
+    assert differences[1].source1 == "test1.jar"
+    assert differences[1].source2 == "test2.jar"
+    zipinfo = differences[1].details[0]
+    classdiff = differences[1].details[1]
     assert zipinfo.source1 == "zipinfo -v {}"
     assert zipinfo.source2 == "zipinfo -v {}"
     assert classdiff.source1 == "com/example/MainActivity.class"
     assert classdiff.source2 == "com/example/MainActivity.class"
-    found_diff = zipinfo.unified_diff + classdiff.details[0].unified_diff
+    found_diff = (
+        differences[0].unified_diff
+        + zipinfo.unified_diff
+        + classdiff.details[0].unified_diff
+    )
     assert expected_diff == found_diff
 
 
- at skip_unless_tools_exist("enjarify", "zipinfo", "javap", "procyon")
+ at skip_unless_tools_exist("enjarify", "zipinfo", "javap", "procyon", "dexdump")
 @skip_unless_tool_is_between("javap", javap_version, "9.0.4", "14.0")
 @skip_unless_tool_is_at_least("enjarify", enjarify_version, "1.0.3")
 def test_differences(differences):
@@ -88,7 +94,7 @@ def test_differences(differences):
     check_dex_differences(differences, expected_diff)
 
 
- at skip_unless_tools_exist("enjarify", "zipinfo", "javap")
+ at skip_unless_tools_exist("enjarify", "zipinfo", "javap", "dexdump")
 @skip_unless_tool_is_at_least("javap", javap_version, "14.0")
 @skip_unless_tool_is_at_least("enjarify", enjarify_version, "1.0.3")
 def test_javap_14_differences(differences):


=====================================
tests/data/dex_expected_diffs
=====================================
@@ -1,3 +1,35 @@
+@@ -1,12 +1,12 @@
+ DEX version '035'
+ DEX file header:
+ magic               : 'dex\n035\0'
+-checksum            : f9ec2d16
+-signature           : dd2a...febb
++checksum            : 15e82cf9
++signature           : 4c3c...b46d
+ file_size           : 2116
+ header_size         : 112
+ link_size           : 0
+ link_off            : 0 (0x000000)
+ string_ids_size     : 40
+ string_ids_off      : 112 (0x000070)
+ type_ids_size       : 17
+@@ -112,15 +112,15 @@
+       ins           : 2
+       outs          : 2
+       insns size    : 11 16-bit code units
+ 000340:                                        |[000340] com.example.MainActivity.onCreate:(Landroid/os/Bundle;)V
+ 000350: 6f20 0100 3200                         |0000: invoke-super {v2, v3}, Landroid/app/Activity;.onCreate:(Landroid/os/Bundle;)V // method at 0001
+ 000356: 1501 037f                              |0003: const/high16 v1, #int 2130903040 // #7f03
+ 00035a: 6e20 0500 1200                         |0005: invoke-virtual {v2, v1}, Lcom/example/MainActivity;.setContentView:(I)V // method at 0005
+-000360: 1a00 1400                              |0008: const-string v0, "Sat Nov 21 14:20:33 CET 2015" // string at 0014
++000360: 1a00 1400                              |0008: const-string v0, "Thu Mar 17 11:54:42 CET 2016" // string at 0014
+ 000364: 0e00                                   |000a: return-void
+       catches       : (none)
+       positions     : 
+         0x0000 line=12
+         0x0003 line=13
+         0x0008 line=14
+         0x000a line=15
 @@ -54,15 +54,15 @@
    version of encoding software:                   2.0
    minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT


=====================================
tests/data/dex_javap_14_expected_diffs
=====================================
@@ -1,3 +1,35 @@
+@@ -1,12 +1,12 @@
+ DEX version '035'
+ DEX file header:
+ magic               : 'dex\n035\0'
+-checksum            : f9ec2d16
+-signature           : dd2a...febb
++checksum            : 15e82cf9
++signature           : 4c3c...b46d
+ file_size           : 2116
+ header_size         : 112
+ link_size           : 0
+ link_off            : 0 (0x000000)
+ string_ids_size     : 40
+ string_ids_off      : 112 (0x000070)
+ type_ids_size       : 17
+@@ -112,15 +112,15 @@
+       ins           : 2
+       outs          : 2
+       insns size    : 11 16-bit code units
+ 000340:                                        |[000340] com.example.MainActivity.onCreate:(Landroid/os/Bundle;)V
+ 000350: 6f20 0100 3200                         |0000: invoke-super {v2, v3}, Landroid/app/Activity;.onCreate:(Landroid/os/Bundle;)V // method at 0001
+ 000356: 1501 037f                              |0003: const/high16 v1, #int 2130903040 // #7f03
+ 00035a: 6e20 0500 1200                         |0005: invoke-virtual {v2, v1}, Lcom/example/MainActivity;.setContentView:(I)V // method at 0005
+-000360: 1a00 1400                              |0008: const-string v0, "Sat Nov 21 14:20:33 CET 2015" // string at 0014
++000360: 1a00 1400                              |0008: const-string v0, "Thu Mar 17 11:54:42 CET 2016" // string at 0014
+ 000364: 0e00                                   |000a: return-void
+       catches       : (none)
+       positions     : 
+         0x0000 line=12
+         0x0003 line=13
+         0x0008 line=14
+         0x000a line=15
 @@ -54,15 +54,15 @@
    version of encoding software:                   2.0
    minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT



View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/-/commit/1bb9b812238bda67d2705a262634a9d0ad3d9eb4

-- 
View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/-/commit/1bb9b812238bda67d2705a262634a9d0ad3d9eb4
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/20230210/19ae6799/attachment.htm>


More information about the rb-commits mailing list