diff options
-rw-r--r-- | src/passes/RemoveUnusedModuleElements.cpp | 3 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 8 | ||||
-rw-r--r-- | test/spec/array-new-data.wast | 4 | ||||
-rw-r--r-- | test/spec/array-new-elem.wast | 12 |
4 files changed, 19 insertions, 8 deletions
diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp index 93cc33563..9449f9034 100644 --- a/src/passes/RemoveUnusedModuleElements.cpp +++ b/src/passes/RemoveUnusedModuleElements.cpp @@ -364,8 +364,7 @@ struct RemoveUnusedModuleElements : public Pass { ModuleElement(ModuleElementKind::Tag, curr->name)) == 0; }); module->removeElementSegments([&](ElementSegment* curr) { - return curr->data.empty() || - analyzer.reachable.count(ModuleElement( + return analyzer.reachable.count(ModuleElement( ModuleElementKind::ElementSegment, curr->name)) == 0; }); // Since we've removed all empty element segments, here we mark all tables diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 165bfd18a..6e75794aa 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -3510,8 +3510,8 @@ public: return sizeFlow; } - auto offset = offsetFlow.getSingleValue().geti32(); - auto size = sizeFlow.getSingleValue().geti32(); + uint64_t offset = offsetFlow.getSingleValue().getUnsigned(); + uint64_t size = sizeFlow.getSingleValue().getUnsigned(); auto heapType = curr->type.getHeapType(); const auto& element = heapType.getArray().element; @@ -3526,7 +3526,7 @@ public: assert(elemType.isNumber()); const auto& seg = *wasm.dataSegments[curr->segment]; auto elemBytes = element.getByteSize(); - auto end = (uint64_t)offset + size * elemBytes; + auto end = offset + size * elemBytes; if ((size != 0ull && droppedSegments.count(curr->segment)) || end > seg.data.size()) { trap("out of bounds segment access in array.new_data"); @@ -3541,7 +3541,7 @@ public: case NewElem: { assert(curr->segment < wasm.elementSegments.size()); const auto& seg = *wasm.elementSegments[curr->segment]; - auto end = (uint64_t)offset + size; + auto end = offset + size; // TODO: Handle dropped element segments once we support those. if (end > seg.data.size()) { trap("out of bounds segment access in array.new_elem"); diff --git a/test/spec/array-new-data.wast b/test/spec/array-new-data.wast index 5d49a0487..f735f7c37 100644 --- a/test/spec/array-new-data.wast +++ b/test/spec/array-new-data.wast @@ -81,10 +81,10 @@ (module (type $vec (array i32)) - (data "\01\00\00\00\02\00\00\00\03\00\00\00\04\00\00\00") + (data "") (func $new-huge (export "new-huge") (result (ref $vec)) - (array.new_data $vec 0 (i32.const 1) (i32.const -1)) + (array.new_data $vec 0 (i32.const 4) (i32.const -1)) ) ) diff --git a/test/spec/array-new-elem.wast b/test/spec/array-new-elem.wast index a61122bd6..d20d8109b 100644 --- a/test/spec/array-new-elem.wast +++ b/test/spec/array-new-elem.wast @@ -46,3 +46,15 @@ (assert_return (invoke "get" (i32.const 1)) (i32.const 2)) (assert_return (invoke "set_get" (i32.const 0) (i32.const 2)) (i32.const 3)) (assert_return (invoke "len") (i32.const 3)) + +(module + (type $vec (array funcref)) + + (elem func) + + (func $new-huge (export "new-huge") (result (ref $vec)) + (array.new_elem $vec 0 (i32.const 1) (i32.const -1)) + ) +) + +(assert_trap (invoke "new-huge") "out of bounds segment access in array.new_data") |