diff --git a/rmp/src/decode/est.rs b/rmp/src/decode/est.rs index 8782105..dcf3f29 100644 --- a/rmp/src/decode/est.rs +++ b/rmp/src/decode/est.rs @@ -161,10 +161,10 @@ impl MessageLen { Marker::Array16 | Marker::Array32 | Marker::Map16 | - Marker::Map32 => self.read_marker_with_len(data, MarkerLen { marker, buf: [0; 4], has: 0 }), + Marker::Map32 | Marker::Ext8 | Marker::Ext16 | - Marker::Ext32 => todo!(), + Marker::Ext32 => self.read_marker_with_len(data, MarkerLen { marker, buf: [0; 4], has: 0 }), Marker::F32 => self.skip_data(data, 4), Marker::F64 => self.skip_data(data, 8), Marker::U8 => self.skip_data(data, 1), @@ -175,11 +175,11 @@ impl MessageLen { Marker::I16 => self.skip_data(data, 2), Marker::I32 => self.skip_data(data, 4), Marker::I64 => self.skip_data(data, 8), - Marker::FixExt1 | - Marker::FixExt2 | - Marker::FixExt4 | - Marker::FixExt8 | - Marker::FixExt16 => todo!(), + Marker::FixExt1 => self.skip_data(data, 2), + Marker::FixExt2 => self.skip_data(data, 3), + Marker::FixExt4 => self.skip_data(data, 5), + Marker::FixExt8 => self.skip_data(data, 9), + Marker::FixExt16 => self.skip_data(data, 17), Marker::FixNeg(_) => Some(()), } } @@ -217,7 +217,7 @@ impl MessageLen { Marker::Str32 => self.skip_data(data, len), Marker::Ext8 | Marker::Ext16 | - Marker::Ext32 => todo!(), + Marker::Ext32 => self.skip_data(data, len + 1), Marker::Array16 | Marker::Array32 => self.read_sequence(data, len), Marker::Map16 | diff --git a/rmp/tests/func/est.rs b/rmp/tests/func/est.rs index d5d484b..a701e55 100644 --- a/rmp/tests/func/est.rs +++ b/rmp/tests/func/est.rs @@ -115,3 +115,37 @@ fn nested() { assert!(MessageLen::with_limits(4, 1 << 16).incremental_len(out.as_slice()).is_err()); assert!(MessageLen::with_limits(14, 1 << 16).incremental_len(out.as_slice()).is_ok()); } + +#[test] +fn extensions() { + let mut out = Vec::with_capacity(263); + + let mut expected = Vec::with_capacity(264); + expected.push(1); + + for len in (0i32..=17).chain([256,257]) { + const TOO_BIG_FOR_U8: i32 = u8::MAX as i32 + 1; + const TOO_BIG_FOR_U16: i32 = u16::MAX as i32 + 1; + + let length_bytes = match len { + 1 | 2 | 4 | 8 | 16 => 0, + ..TOO_BIG_FOR_U8 => 1, + TOO_BIG_FOR_U8..TOO_BIG_FOR_U16 => 2, + _ => 4, + }; + + let len_with_prefix = |len| 1 + length_bytes + 1 + len; + let msg_len = len_with_prefix(len); + + expected.truncate(1); + expected.resize(1 + length_bytes as usize, 1 + length_bytes); + expected.resize(msg_len as usize, msg_len); + expected.push(-msg_len); + + out.clear(); + write_ext_meta(&mut out, len as u32, 0x67).unwrap(); + out.resize(out.len() + len as usize, 0xab); + + check_estimates(&out, &expected); + } +}