diff --git a/src/reader.rs b/src/reader.rs index 6f72bf0..1c44e2e 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -465,6 +465,12 @@ impl<'wasm> Reader<'wasm> { VA: Allocator, { let len = self.read_u32()?; + // Reject lengths that cannot form a valid allocation layout. On 32-bit + // targets Layout::array overflows for huge declared lengths and used to + // panic inside Vec::new_in; return VecTooLong like the stack path (#158). + if core::alloc::Layout::array::(len as usize).is_err() { + return Err(ValidationError::VecTooLong); + } let mut out = Vec::new_in(alloc, len)?; for _ in 0..len { out.push(read_element(self)?); diff --git a/tests/regression/decode-errors.wast b/tests/regression/decode-errors.wast index f40a22f..811e5a1 100644 --- a/tests/regression/decode-errors.wast +++ b/tests/regression/decode-errors.wast @@ -179,3 +179,12 @@ (assert_invalid (module binary "\00asm\01\00\00\00\01\04\01\60\00\00\03\02\01\00\0a\08\01\06\01\ff\ff\03\7f\0b") "call frame too large") + +;; --------------------------------------------------------------------------- +;; A type section declaring 0xFFFFFFFF entries must not panic the heap vector +;; path on 32-bit targets (Layout::array overflow). Regression for #158. +;; --------------------------------------------------------------------------- +(assert_invalid + (module binary "\00asm\01\00\00\00\01\05\ff\ff\ff\ff\0f") + "length out of bounds") +