diff --git a/res/cases/v1/err-leb-i32-too-long-2.wasm b/res/cases/v1/err-leb-i32-too-long-2.wasm new file mode 100644 index 0000000..3fe114c Binary files /dev/null and b/res/cases/v1/err-leb-i32-too-long-2.wasm differ diff --git a/res/cases/v1/err-leb-u32-too-long.wasm b/res/cases/v1/err-leb-u32-too-long.wasm new file mode 100644 index 0000000..1e5a358 Binary files /dev/null and b/res/cases/v1/err-leb-u32-too-long.wasm differ diff --git a/spec/testsuite b/spec/testsuite index c538faa..8958a44 160000 --- a/spec/testsuite +++ b/spec/testsuite @@ -1 +1 @@ -Subproject commit c538faa43217146f458b9bc2d4b704d0a4d80963 +Subproject commit 8958a44bf8b3dbf9e48dd1c44ee566e8bf682abe diff --git a/src/elements/primitives.rs b/src/elements/primitives.rs index 084cce6..fe9fc05 100644 --- a/src/elements/primitives.rs +++ b/src/elements/primitives.rs @@ -47,6 +47,9 @@ impl Deserialize for VarUint32 { res |= (b & 0x7f).checked_shl(shift).ok_or(Error::InvalidVarUint32)?; shift += 7; if (b >> 7) == 0 { + if shift >= 32 && (b as u8).leading_zeros() < 4 { + return Err(Error::InvalidVarInt32); + } break; } } @@ -100,6 +103,9 @@ impl Deserialize for VarUint64 { res |= (b & 0x7f).checked_shl(shift).ok_or(Error::InvalidVarUint64)?; shift += 7; if (b >> 7) == 0 { + if shift >= 64 && (b as u8).leading_zeros() < 7 { + return Err(Error::InvalidVarInt64); + } break; } } @@ -288,11 +294,11 @@ impl Deserialize for VarInt32 { if shift < 32 && b & 0b0100_0000 == 0b0100_0000 { res |= (1i32 << shift).wrapping_neg(); } else if shift >= 32 && b & 0b0100_0000 == 0b0100_0000 { - if (!(b | 0b1000_0000)).leading_zeros() < 4 { + if (!(b | 0b1000_0000)).leading_zeros() < 5 { return Err(Error::InvalidVarInt32); } } else if shift >= 32 && b & 0b0100_0000 == 0 { - if b.leading_zeros() < 4 { + if b.leading_zeros() < 5 { return Err(Error::InvalidVarInt32); } } @@ -828,6 +834,24 @@ mod tests { ); } + #[test] + fn varuint32_too_long_trailing() { + assert!( + deserialize_buffer::( + &[0xff, 0xff, 0xff, 0xff, 0x7f][..], + ).is_err() + ); + } + + #[test] + fn varuint64_too_long_trailing() { + assert!( + deserialize_buffer::( + &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04][..], + ).is_err() + ); + } + #[test] fn varint32_min() { varint32_serde_test(