[Git][reproducible-builds/diffoscope][master] Add support for comparing WebAssembly modules. (MR: !17)

Chris Lamb gitlab at salsa.debian.org
Thu Dec 13 16:11:35 CET 2018


Chris Lamb pushed to branch master at Reproducible Builds / diffoscope


Commits:
b65fc3fa by Joachim Breitner at 2018-12-13T15:10:56Z
Add support for comparing WebAssembly modules. (MR: !17)

This only defines one WebAssembly dumper in wasm.py ideally, I’d run
`wasm2wat` and if that does not show the difference, run `wasm-objdump`.
Which is a general pattern that should be abstracted in the `Difference`
class somewhere. Might do if the itch becomes large enough, but not
right now.

requires `wabt`, which is not packaged for Debian yet, but is available
elsewhere, e.g. in Arch and nixpkgs.

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

- - - - -


7 changed files:

- diffoscope/comparators/__init__.py
- + diffoscope/comparators/wasm.py
- diffoscope/external_tools.py
- + tests/comparators/test_wasm.py
- + tests/data/hello1.wasm
- + tests/data/hello2.wasm
- + tests/data/wasm_expected_diff


Changes:

=====================================
diffoscope/comparators/__init__.py
=====================================
@@ -58,6 +58,7 @@ class ComparatorManager(object):
         ('elf.StaticLibFile',),
         ('llvm.LlvmBitCodeFile',),
         ('sqlite.Sqlite3Database',),
+        ('wasm.WasmFile',),
         ('fonts.TtfFile',),
         ('fontconfig.FontconfigCacheFile',),
         ('gettext.MoFile',),


=====================================
diffoscope/comparators/wasm.py
=====================================
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+#
+# diffoscope: in-depth comparison of files, archives, and directories
+#
+# Copyright © 2018 Joachim Breitner <nomeata at debian.org>
+#
+# 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 re
+
+from diffoscope.tools import tool_required
+from diffoscope.difference import Difference
+
+from .utils.file import File
+from .utils.command import Command
+
+WASM_MAGIC = b"\x00asm"
+
+
+class Wasm2Wat(Command):
+    @tool_required('wasm2wat')
+    def cmdline(self):
+        return ['wasm2wat', '--no-check', self.path]
+
+
+class WasmFile(File):
+    DESCRIPTION = "WebAssembly binary module"
+    FILE_EXTENSION_SUFFIX = '.wasm'
+
+    @classmethod
+    def recognizes(cls, file):
+        if not super().recognizes(file):
+            return False
+        with open(file.path, 'rb') as f:
+            magic = f.read(4)
+            return magic == WASM_MAGIC
+
+    def compare_details(self, other, source=None):
+        return [Difference.from_command(Wasm2Wat, self.path, other.path)]


=====================================
diffoscope/external_tools.py
=====================================
@@ -240,6 +240,9 @@ EXTERNAL_TOOLS = {
         'arch': 'sqlite',
         'FreeBSD': 'sqlite3',
     },
+    'wasm2wat': {
+        'arch': 'wabt',
+    },
     'tar': {
         'debian': 'tar',
         'arch': 'tar',


=====================================
tests/comparators/test_wasm.py
=====================================
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+#
+# diffoscope: in-depth comparison of files, archives, and directories
+#
+# Copyright © 2018 Joachim Breitner <nomeata at debian.org>
+#
+# 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.wasm import WasmFile
+
+from ..utils.data import load_fixture, get_data
+from ..utils.tools import skip_unless_tools_exist
+from ..utils.nonexisting import assert_non_existing
+
+
+wasmmodule1 = load_fixture('hello1.wasm')
+wasmmodule2 = load_fixture('hello2.wasm')
+
+
+def test_identification(wasmmodule1):
+    assert isinstance(wasmmodule1, WasmFile)
+
+
+def test_no_differences(wasmmodule1):
+    difference = wasmmodule1.compare(wasmmodule1)
+    assert difference is None
+
+
+ at pytest.fixture
+def differences(wasmmodule1, wasmmodule2):
+    return wasmmodule1.compare(wasmmodule2).details
+
+
+ at skip_unless_tools_exist('wasm2wat')
+def test_diff(differences):
+    expected_diff = get_data('wasm_expected_diff')
+    actual_diff = differences[0].unified_diff
+    assert actual_diff == expected_diff
+
+
+ at skip_unless_tools_exist('wasm2wat')
+def test_compare_non_existing(monkeypatch, wasmmodule1):
+    assert_non_existing(monkeypatch, wasmmodule1, has_null_source=False)


=====================================
tests/data/hello1.wasm
=====================================
Binary files /dev/null and b/tests/data/hello1.wasm differ


=====================================
tests/data/hello2.wasm
=====================================
@@ -0,0 +1,3 @@
+00000000: 0061 736d 0100 0000 0104 0160 0000 020a  .asm.......`....
+00000010: 0100 0568 656c 6c6f 0000 0302 0100 0707  ...hello........
+00000020: 0103 7275 6e00 010a 0601 0400 1000 0b    ..run..........


=====================================
tests/data/wasm_expected_diff
=====================================
@@ -0,0 +1,11 @@
+@@ -1,6 +1,8 @@
+ (module
+   (type (;0;) (func))
+-  (import "" "hello" (func (;0;) (type 0)))
++  (import "" "world" (func (;0;) (type 0)))
+   (func (;1;) (type 0)
++    nop)
++  (func (;2;) (type 0)
+     call 0)
+-  (export "run" (func 1)))
++  (export "run" (func 2)))



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

-- 
View it on GitLab: https://salsa.debian.org/reproducible-builds/diffoscope/commit/b65fc3fa288c89ff3f10dcd5cb2434b0e3df4869
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/20181213/368909f7/attachment.html>


More information about the rb-commits mailing list