diff --git a/crates/wasmparser/src/module_resources.rs b/crates/wasmparser/src/module_resources.rs index bdf137ce12..85cb2790c9 100644 --- a/crates/wasmparser/src/module_resources.rs +++ b/crates/wasmparser/src/module_resources.rs @@ -13,7 +13,7 @@ * limitations under the License. */ -use crate::{FuncType, GlobalType, MemoryType, TableType, Type}; +use crate::{EventType, FuncType, GlobalType, MemoryType, TableType, Type}; use std::ops::Range; /// Types that qualify as Wasm function types for validation purposes. @@ -202,6 +202,8 @@ pub trait WasmModuleResources { fn table_at(&self, at: u32) -> Option; /// Returns the linear memory at given index. fn memory_at(&self, at: u32) -> Option; + /// Returns the event at given index. + fn event_at(&self, at: u32) -> Option; /// Returns the global variable at given index. fn global_at(&self, at: u32) -> Option; /// Returns the `FuncType` associated with the given type index. @@ -232,6 +234,9 @@ where fn memory_at(&self, at: u32) -> Option { T::memory_at(self, at) } + fn event_at(&self, at: u32) -> Option { + T::event_at(self, at) + } fn global_at(&self, at: u32) -> Option { T::global_at(self, at) } diff --git a/crates/wasmparser/src/operators_validator.rs b/crates/wasmparser/src/operators_validator.rs index 991f337b1f..3b5c5a9dcf 100644 --- a/crates/wasmparser/src/operators_validator.rs +++ b/crates/wasmparser/src/operators_validator.rs @@ -23,7 +23,9 @@ // the various methods here. use crate::limits::MAX_WASM_FUNCTION_LOCALS; -use crate::primitives::{MemoryImmediate, Operator, SIMDLaneIndex, Type, TypeOrFuncType}; +use crate::primitives::{ + EventType, MemoryImmediate, Operator, SIMDLaneIndex, Type, TypeOrFuncType, +}; use crate::{BinaryReaderError, Result, WasmFeatures, WasmFuncType, WasmModuleResources}; /// A wrapper around a `BinaryReaderError` where the inner error's offset is a @@ -598,7 +600,8 @@ impl OperatorValidator { Operator::Throw { index } => { self.check_exceptions_enabled()?; // Check values associated with the exception. - let ty = func_type_at(&resources, index)?; + let event_ty = event_at(&resources, index)?; + let ty = func_type_at(&resources, event_ty.type_index)?; for ty in ty.inputs().rev() { self.pop_operand(Some(ty))?; } @@ -620,7 +623,8 @@ impl OperatorValidator { let (ty, kind) = self.jump(relative_depth)?; self.pop_operand(Some(Type::ExnRef))?; // Check the exception's argument values with target block's. - let exn_args = func_type_at(&resources, index)?; + let event_ty = event_at(&resources, index)?; + let exn_args = func_type_at(&resources, event_ty.type_index)?; if Iterator::ne(exn_args.inputs(), label_types(ty, resources, kind)?) { bail_op_err!("target block types do not match"); } @@ -1842,6 +1846,12 @@ fn func_type_at( .ok_or_else(|| OperatorValidatorError::new("unknown type: type index out of bounds")) } +fn event_at(resources: &T, at: u32) -> OperatorValidatorResult { + resources + .event_at(at) + .ok_or_else(|| OperatorValidatorError::new("unknown event: event index out of bounds")) +} + enum Either { A(A), B(B), diff --git a/crates/wasmparser/src/validator.rs b/crates/wasmparser/src/validator.rs index 88e9bfe8fb..c975baad8b 100644 --- a/crates/wasmparser/src/validator.rs +++ b/crates/wasmparser/src/validator.rs @@ -1838,6 +1838,10 @@ impl WasmModuleResources for ValidatorResources { self.0.get_memory(self.0.def(at)).copied() } + fn event_at(&self, at: u32) -> Option { + self.0.get_event(self.0.def(at)).copied() + } + fn global_at(&self, at: u32) -> Option { self.0.get_global(self.0.def(at)).map(|t| t.item) } diff --git a/crates/wasmparser/src/validator/func.rs b/crates/wasmparser/src/validator/func.rs index 791827aff2..0a05713d57 100644 --- a/crates/wasmparser/src/validator/func.rs +++ b/crates/wasmparser/src/validator/func.rs @@ -130,6 +130,9 @@ mod tests { fn memory_at(&self, _at: u32) -> Option { todo!() } + fn event_at(&self, _at: u32) -> Option { + todo!() + } fn global_at(&self, _at: u32) -> Option { todo!() } diff --git a/tests/local/exception-handling.wast b/tests/local/exception-handling.wast index ba97155ca7..62bc99c538 100644 --- a/tests/local/exception-handling.wast +++ b/tests/local/exception-handling.wast @@ -27,3 +27,17 @@ end ) ) + +(assert_invalid + (module + (type (func)) + (func throw 0)) + "unknown event: event index out of bounds") + +(assert_invalid + (module + (type (func)) + (func (param exnref) + local.get 0 + br_on_exn 0 0)) + "unknown event: event index out of bounds")