diff --git a/src/validator/cbor.rs b/src/validator/cbor.rs index 34d54155..fce1ec4d 100644 --- a/src/validator/cbor.rs +++ b/src/validator/cbor.rs @@ -3060,7 +3060,10 @@ where Some(Token::LE) if i128::from(*i) <= *v as i128 => None, Some(Token::GT) if i128::from(*i) > *v as i128 => None, Some(Token::GE) if i128::from(*i) >= *v as i128 => None, - Some(Token::SIZE) if i128::from(*i) < 256i128.pow(*v as u32) => None, + Some(Token::SIZE) => match 256i128.checked_pow(*v as u32) { + Some(n) if i128::from(*i) < n => None, + _ => Some(format!("expected value .size {}, got {:?}", v, i)), + }, Some(Token::BITS) => { if let Some(sv) = 1u32.checked_shl(*v as u32) { if (i128::from(*i) & sv as i128) != 0 { diff --git a/src/validator/json.rs b/src/validator/json.rs index 6eb68cdd..f19cff6f 100644 --- a/src/validator/json.rs +++ b/src/validator/json.rs @@ -2228,7 +2228,10 @@ impl<'a> Visitor<'a, Error> for JSONValidator<'a> { Some(Token::LE) if i <= *v as u64 => None, Some(Token::GT) if i > *v as u64 => None, Some(Token::GE) if i >= *v as u64 => None, - Some(Token::SIZE) if i < 256u64.pow(*v as u32) => None, + Some(Token::SIZE) => match 256u128.checked_pow(*v as u32) { + Some(n) if (i as u128) < n => None, + _ => Some(format!("expected value .size {}, got {}", v, n)), + }, #[cfg(feature = "additional-controls")] Some(Token::PLUS) => { if i == *v as u64 { @@ -2594,4 +2597,33 @@ mod tests { Ok(()) } + + #[test] + fn size_control_validation_error() -> std::result::Result<(), Box> { + let cddl = indoc!( + r#" + start = Record + Record = { + id: Id + } + Id = uint .size 8 + "# + ); + + let json = r#"{ "id": 5 }"#; + + let cddl = cddl_from_str(cddl, true).map_err(json::Error::CDDLParsing); + if let Err(e) = &cddl { + println!("{}", e); + } + + let json = serde_json::from_str::(json).map_err(json::Error::JSONParsing)?; + + let cddl = cddl.unwrap(); + + let mut jv = JSONValidator::new(&cddl, json, None); + jv.validate()?; + + Ok(()) + } }