Repository: bytecodealliance/wasm-tools
Pull request #1968 (2025-01-07 07:41:27)

wasmparser: Fix subtyping depth indexing
fix: https://github.com/bytecodealliance/wasm-tools/issues/1967

This patch addresses an issue in subtyping depth checking where `set_subtyping_depth` indexes the depth by `CoreTypeId`, but `get_subtyping_depth` accesses it using `CoreTypeId#index` (`u32`). This leads to "IndexMap: index out of bounds" error when validating WasmGC components with subtypes.


alexcrichton: Thanks for the report, the investigation, and a PR! I believe this is the right fix as well. Playing around with this locally this is a small test case to trigger the bug from before and this PR fixes it. If you'd like to include that here I'd be happy to flag this for merge:

```diff
diff --git a/tests/local/component-model/gc.wast b/tests/local/component-model/gc.wast
index 1b409903f..d7a47456e 100644
--- a/tests/local/component-model/gc.wast
+++ b/tests/local/component-model/gc.wast
@@ -124,3 +124,12 @@
     ))
   )
   "sub type cannot have a final super type")
+
+(component
+  (type $t (resource (rep i32)))
+  (core func (canon resource.drop $t))
+  (core module
+    (type $t1 (sub (func)))
+    (type (sub $t1 (func)))
+  )
+)
```
tanishiking: Thank you so much for taking a look & minimizing the reproduction @alexcrichton !
I added the test case you mentioned :)

Patch:
diff --git a/crates/wasmparser/src/validator/types.rs b/crates/wasmparser/src/validator/types.rs
index d8bce0b8..9898608b 100644
--- a/crates/wasmparser/src/validator/types.rs
+++ b/crates/wasmparser/src/validator/types.rs
@@ -995,7 +995,7 @@ impl TypeList {
         let depth = self
             .core_type_to_depth
             .as_ref()
-            .expect("cannot get subtype depth from a committed list")[id.index()];
+            .expect("cannot get subtype depth from a committed list")[&id];
         debug_assert!(usize::from(depth) <= crate::limits::MAX_WASM_SUBTYPING_DEPTH);
         depth
     }


Test patch:
diff --git a/tests/local/component-model/gc.wast b/tests/local/component-model/gc.wast
index 1b409903..d7a47456 100644
--- a/tests/local/component-model/gc.wast
+++ b/tests/local/component-model/gc.wast
@@ -124,3 +124,12 @@
     ))
   )
   "sub type cannot have a final super type")
+
+(component
+  (type $t (resource (rep i32)))
+  (core func (canon resource.drop $t))
+  (core module
+    (type $t1 (sub (func)))
+    (type (sub $t1 (func)))
+  )
+)
diff --git a/tests/snapshots/local/component-model/gc.wast.json b/tests/snapshots/local/component-model/gc.wast.json
index 86f77a12..68f08e21 100644
--- a/tests/snapshots/local/component-model/gc.wast.json
+++ b/tests/snapshots/local/component-model/gc.wast.json
@@ -78,6 +78,12 @@
       "filename": "gc.11.wasm",
       "module_type": "binary",
       "text": "sub type cannot have a final super type"
+    },
+    {
+      "type": "module",
+      "line": 128,
+      "filename": "gc.12.wasm",
+      "module_type": "binary"
     }
   ]
 }
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/gc.wast/12.print b/tests/snapshots/local/component-model/gc.wast/12.print
new file mode 100644
index 00000000..40910eb4
--- /dev/null
+++ b/tests/snapshots/local/component-model/gc.wast/12.print
@@ -0,0 +1,8 @@
+(component
+  (type $t (;0;) (resource (rep i32)))
+  (core func (;0;) (canon resource.drop $t))
+  (core module (;0;)
+    (type $t1 (;0;) (sub (func)))
+    (type (;1;) (sub $t1 (func)))
+  )
+)