bencode inspired tight self describing serialization format
Diffstat (limited to 'src/de.rs')
| -rw-r--r-- | src/de.rs | 24 |
1 files changed, 23 insertions, 1 deletions
@@ -13,6 +13,18 @@ pub fn from_bytes<'a, T: Deserialize<'a>>(x: &'a [u8]) -> Result<T> { let mut d = Deserializer { r: x }; T::deserialize(&mut d) } +#[test] +fn de_leb128() { + use atools::prelude::*; + dbg!( + Deserializer { + r: &[0x80; 18].join(04) + } + .leb128() + .unwrap() + ); +} + impl<'de> Deserializer<'de> { pub fn leb128(&mut self) -> Result<u128> { let mut res = 0u128; @@ -20,6 +32,9 @@ impl<'de> Deserializer<'de> { let mut b = 128; while b & 128 != 0 { b = self.r.r::<u8>()?; + if shift == 18 && b > 0b11 { + return Err(Error::Overflow); + } res |= ((b & 127) as u128) .checked_shl(shift * 7) .ok_or(Error::Overflow)?; @@ -33,12 +48,19 @@ impl<'de> Deserializer<'de> { let mut b = 128; while b & 128 != 0 { b = self.r.r::<u8>()?; + if shift > 18 || (shift == 18 && !matches!(b & 127, 0..=1 | 126..=127)) { + return Err(Error::Overflow); + } + if shift == 18 + && let 0..=1 | 126..=127 = b + {} + res |= ((b & 127) as u128) .checked_shl(shift * 7) .ok_or(Error::Overflow)?; shift += 1; } - if (shift < 128) && ((b & 64) != 0) { + if (shift * 7 < 128) && (b & 64) != 0 { res |= (!0u128).checked_shl(shift * 7).ok_or(Error::Overflow)?; } Ok(res.cast_signed()) |