diff --git a/src/support/serde.rs b/src/support/serde.rs index 4a8450d4..5c6edd53 100644 --- a/src/support/serde.rs +++ b/src/support/serde.rs @@ -72,6 +72,21 @@ impl<'de, const BITS: usize, const LIMBS: usize> Visitor<'de> for StrVisitor::ZERO); + } else { + return Err(Error::invalid_value(Unexpected::Str(value), &self)); + } + } else if nbytes(BITS) * 2 < value.len() { + return Err(Error::invalid_length(value.len(), &self)); + } + let mut limbs = [0; LIMBS]; for (i, chunk) in value.as_bytes().rchunks(16).enumerate() { let chunk = str::from_utf8(chunk) @@ -163,4 +178,52 @@ mod tests { }); }); } + + #[test] + fn test_serde_invalid_size_error() { + // Test that if we add a character to a value that is already the max length for + // the given number of bits, we get an error. + const_for!(BITS in SIZES { + const LIMBS: usize = nlimbs(BITS); + let value = Uint::::MAX; + let mut serialized = serde_json::to_string(&value).unwrap(); + + // ensure format of serialized value is correct ("0x...") + assert_eq!(&serialized[..3], "\"0x"); + // last character should be a quote + assert_eq!(&serialized[serialized.len() - 1..], "\""); + + // strip the last character, add a zero, and finish with a quote + serialized.pop(); + serialized.push('0'); + serialized.push('"'); + let deserialized = serde_json::from_str::>(&serialized); + assert!(deserialized.is_err()); + }); + } + + #[test] + fn test_serde_zero_invalid_size_error() { + // Test that if we add a zero to a large zero string, we get an error. + // This is done by replacing a max string `0xffff...` with zeros: `0x0000...` + const_for!(BITS in SIZES { + const LIMBS: usize = nlimbs(BITS); + let value = Uint::::MAX; + let mut serialized = serde_json::to_string(&value).unwrap(); + + // replace `f`s with `0`s + serialized = serialized.replace('f', "0"); + // ensure format of serialized value is correct ("0x...") + assert_eq!(&serialized[..3], "\"0x"); + // last character should be a quote + assert_eq!(&serialized[serialized.len() - 1..], "\""); + + // strip the last character, add a zero, and finish with a quote + serialized.pop(); + serialized.push('0'); + serialized.push('"'); + let deserialized = serde_json::from_str::>(&serialized); + assert!(deserialized.is_err()); + }); + } }