Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/ir.cc
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,13 @@ void MakeTypeBindingReverseMapping(
out_reverse_mapping->clear();
out_reverse_mapping->resize(num_types);
for (const auto& [name, binding] : bindings) {
assert(static_cast<size_t>(binding.index) < out_reverse_mapping->size());
(*out_reverse_mapping)[binding.index] = name;
// A binding index can come straight from the name section's local
// subsection, which is not otherwise range-checked against the function's
// local count, so skip entries that fall outside the mapping instead of
// writing past it.
if (static_cast<size_t>(binding.index) < out_reverse_mapping->size()) {
(*out_reverse_mapping)[binding.index] = name;
}
}
}

Expand Down
34 changes: 34 additions & 0 deletions test/binary/local-name-index-out-of-range.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
;;; TOOL: run-gen-wasm
;; The name section's local subsection can carry a local index that is out of
;; range for the function it names. The reader accepts such an entry, so
;; MakeTypeBindingReverseMapping used to write past the reverse-mapping vector
;; (heap overflow in a release build, assert in a debug build). The out of range
;; name is now dropped and wasm2wat prints the module unchanged.
magic
version
section(TYPE) {
count[1]
function params[1] i32 results[0]
}
section(FUNCTION) {
count[1]
type[0]
}
section(CODE) {
count[1]
func { locals[0] }
}
section("name") {
section(NAME_LOCALS) {
func_count[1]
index[0]
local_count[1]
index[5] ;; function has a single param (index 0), so 5 is invalid
str("BAD")
}
}
(;; STDOUT ;;;
(module
(type (;0;) (func (param i32)))
(func (;0;) (type 0) (param i32)))
;;; STDOUT ;;)
Loading