webassemblyjs icon indicating copy to clipboard operation
webassemblyjs copied to clipboard

wasm-edit fails to update locs in AST for partial edits within a section

Open TimHambourger opened this issue 7 years ago • 0 comments

I noticed this while submitting #413. If you add the following test to ast-sync.js, it will fail:

diff --git a/packages/wasm-edit/test/ast-sync.js b/packages/wasm-edit/test/ast-sync.js
index 58be237..b0b4da1 100644
--- a/packages/wasm-edit/test/ast-sync.js
+++ b/packages/wasm-edit/test/ast-sync.js
@@ -109,6 +109,17 @@ function renameImports(name) {
   };
 }

+function renameFirstImportOnly(name) {
+  let i = 0;
+  return {
+    ModuleImport({ node }) {
+      if (!i++) {
+        node.module = node.name = name;
+      }
+    }
+  }
+}
+
 describe("AST synchronization", () => {
   // (module)
   const bin = makeBuffer(
@@ -136,7 +147,9 @@ describe("AST synchronization", () => {

     b => addWithAST(ast, b, [makeFuncImportNode()]),

-    b => editWithAST(ast, b, renameImports("c"))
+    b => editWithAST(ast, b, renameImports("c")),
+
+    b => editWithAST(ast, b, renameFirstImportOnly("abc"))
   ];

   it("should run steps", function() {
failed at step b => editWithAST(ast, b, renameFirstImportOnly("abc"))
... and later ...
            {
              "type": "ModuleImport",
              "module": "c",
              "name": "c",
              "descr": {
                "type": "FuncImportDescr",
                "id": {
                  "type": "NumberLiteral",
                  "value": 0
                },
                "signature": {
                  "type": "Signature",
                  "params": [],
                  "results": []
                }
              },
              "loc": {
                "start": {
                  "line": -1,
  -               "column": 28
  +               "column": 24
                },
                "end": {
                  "line": -1,
  -               "column": 34
  +               "column": 30
                }
              }
            },

The issue is that applyOperations updates the locs for nodes with a pending operation and for nodes in later sections (thanks to shiftSection descending into child nodes). But it misses nodes in the current section with no pending operation. If you were to later reuse this AST to edit that 2nd import, I'd expect that your WASM would get corrupted.

I think the fix here likely hits the same spot touched by #413. I debated submitting a single PR that covers both, but decided they were functionally separate enough that it was better to split. But this means it might be easier to fix these one at a time instead of in parallel.

TimHambourger avatar Jul 14 '18 04:07 TimHambourger