bencode inspired tight self describing serialization format
Diffstat (limited to 'src/de.rs')
-rw-r--r--src/de.rs24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/de.rs b/src/de.rs
index 175c147..e1f29d2 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -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())