Reject overflowing u32 varints

Found while testing crates/format/src/fig/kiwi.rs:190

Co-Authored-By: GPT-5.6-Luna <noreply@openai.com>
Co-Authored-By: GPT-6-Luna <noreply@openai.com>
This commit is contained in:
Max MittelstädtandGPT-5.6-Luna committed 2026-11-01 10:09:26 +00:00
1 parent 53259cf50e
commit 3f7f5f38ce
1 file changed
+20 -2
+20 -2
View File
@@ -187,9 +187,13 @@ impl<'b> Reader<'b> {
let mut shift = 0;
loop {
let b = self.byte()?;
value |= u32::from(b & 127).checked_shl(shift).unwrap_or(0);
let part = b & 127;
if shift == 28 && (part > 0x0f || b & 128 != 0) {
return err("u32 varint overflow");
}
value |= u32::from(part) << shift;
shift += 7;
if b & 128 == 0 || shift >= 35 {
if b & 128 == 0 {
return Ok(value);
}
}
@@ -640,3 +644,17 @@ fn numbered(token: &str, default: u32) -> Result<(String, u32), KiwiError> {
Some((name, n)) => Ok((name.to_string(), n.parse().map_err(|_| KiwiError(format!("schema text: bad number in `{token}`")))?)),
}
}
#[cfg(test)]
mod tests {
use super::Reader;
#[test]
fn overflowing_u32_varint_is_rejected() {
let mut boundary = Reader { data: &[0xff, 0xff, 0xff, 0xff, 0x0f], pos: 0 };
assert_eq!(boundary.var_uint(), Ok(u32::MAX));
let mut overflowing = Reader { data: &[0xff, 0xff, 0xff, 0xff, 0x7f], pos: 0 };
assert!(overflowing.var_uint().is_err(), "overflowing u32 varint was accepted");
}
}