diff --git a/res/cases/v1/const.wasm b/res/cases/v1/const.wasm index d00d02c..6d5035d 100644 Binary files a/res/cases/v1/const.wasm and b/res/cases/v1/const.wasm differ diff --git a/res/cases/v1/const.wast b/res/cases/v1/const.wast index 8aae69e..8cf1632 100644 --- a/res/cases/v1/const.wast +++ b/res/cases/v1/const.wast @@ -17,6 +17,8 @@ i32.const -8192 i32.const -16384 i32.const -32768 + i32.const -2147483648 + i32.const 2147483647 return ) ) diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 502d4ea..03b3345 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -57,11 +57,11 @@ pub enum Error { /// Unsupported version UnsupportedVersion(u32), /// Inconsistence between declared and actual length - InconsistentLength { + InconsistentLength { /// Expected length of the definition - expected: usize, + expected: usize, /// Actual length of the definition - actual: usize + actual: usize }, /// Other static error Other(&'static str), @@ -81,6 +81,10 @@ pub enum Error { UnknownOpcode(u8), /// Invalid VarUint1 value InvalidVarUint1(u8), + /// Invalid VarInt32 value + InvalidVarInt32, + /// Invalid VarInt64 value + InvalidVarInt64, } impl From for Error { @@ -133,8 +137,8 @@ pub fn serialize(val: T) -> Result, T::Error> { } /// Serialize module to the file -pub fn serialize_to_file>(p: P, module: Module) -> Result<(), Error> -{ +pub fn serialize_to_file>(p: P, module: Module) -> Result<(), Error> +{ let mut io = ::std::fs::File::create(p)?; module.serialize(&mut io) } \ No newline at end of file diff --git a/src/elements/module.rs b/src/elements/module.rs index 75de0cf..a3fdf8a 100644 --- a/src/elements/module.rs +++ b/src/elements/module.rs @@ -275,7 +275,7 @@ mod integration_tests { let module = deserialize_file("./res/cases/v1/const.wasm").expect("Should be deserialized"); let func = &module.code_section().expect("Code section to exist").bodies()[0]; - assert_eq!(func.code().elements().len(), 18); + assert_eq!(func.code().elements().len(), 20); assert_eq!(I64Const(9223372036854775807), func.code().elements()[0]); assert_eq!(I64Const(-9223372036854775808), func.code().elements()[1]); @@ -293,6 +293,8 @@ mod integration_tests { assert_eq!(I32Const(-8192), func.code().elements()[13]); assert_eq!(I32Const(-16384), func.code().elements()[14]); assert_eq!(I32Const(-32768), func.code().elements()[15]); + assert_eq!(I32Const(-2147483648), func.code().elements()[16]); + assert_eq!(I32Const(2147483647), func.code().elements()[17]); } #[test] diff --git a/src/elements/primitives.rs b/src/elements/primitives.rs index a5aef1c..1b59f7e 100644 --- a/src/elements/primitives.rs +++ b/src/elements/primitives.rs @@ -230,6 +230,7 @@ impl Deserialize for VarInt32 { let mut shift = 0; let mut u8buf = [0u8; 1]; loop { + if shift > 31 { return Err(Error::InvalidVarInt32); } reader.read_exact(&mut u8buf)?; let b = u8buf[0]; @@ -293,13 +294,13 @@ impl Deserialize for VarInt64 { let mut shift = 0; let mut u8buf = [0u8; 1]; loop { + if shift > 63 { return Err(Error::InvalidVarInt64); } reader.read_exact(&mut u8buf)?; let b = u8buf[0]; res |= ((b & 0x7f) as i64) << shift; shift += 7; if (b >> 7) == 0 { - println!("shifting {}, b = {:b}, res = {:b}", shift, b, res); if shift < 64 && b & 0b0100_0000 == 0b0100_0000 { res |= (1i64 << shift).wrapping_neg(); } @@ -690,6 +691,39 @@ mod tests { varint64_serde_test(vec![0x80, 0x40], -8192); } + #[test] + fn varint64_min() { + varint64_serde_test( + vec![0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f], + -9223372036854775808, + ); + } + + #[test] + fn varint64_max() { + varint64_serde_test( + vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00], + 9223372036854775807, + ); + } + + #[test] + fn varint32_min() { + varint32_serde_test( + vec![0x80, 0x80, 0x80, 0x80, 0x78], + -2147483648, + ); + } + + #[test] + fn varint32_max() { + varint32_serde_test( + vec![0xff, 0xff, 0xff, 0xff, 0x07], + 2147483647, + ); + } + + #[test] fn counted_list() { let payload = vec![