diff --git a/serde-tests/test.rs b/serde-tests/test.rs index 9764d71d..0e4e17d3 100644 --- a/serde-tests/test.rs +++ b/serde-tests/test.rs @@ -1405,3 +1405,9 @@ fn non_human_readable() { assert_eq!(human_readable, expected); assert_eq!(human_readable, non_human_readable); } + +#[test] +fn invalid_length() { + // This is a regression test for fuzzer-generated input (RUST-1240). + assert!(bson::from_slice::(&[4, 0, 0, 128, 0, 87]).is_err()); +} diff --git a/src/de/raw.rs b/src/de/raw.rs index 2f539c19..52701fd2 100644 --- a/src/de/raw.rs +++ b/src/de/raw.rs @@ -171,9 +171,11 @@ impl<'de> Deserializer<'de> { where F: FnOnce(DocumentAccess<'_, 'de>) -> Result, { - let mut length_remaining = read_i32(&mut self.bytes)? - .checked_sub(4) - .ok_or_else(|| Error::custom("invalid length, less than min document size"))?; + let mut length_remaining = read_i32(&mut self.bytes)?; + if length_remaining < 4 { + return Err(Error::custom("invalid length, less than min document size")); + } + length_remaining -= 4; let out = f(DocumentAccess { root_deserializer: self, length_remaining: &mut length_remaining,