Skip to content

Commit

Permalink
fix: validate integers before encoding. (#15)
Browse files Browse the repository at this point in the history
Integers in CBOR range from -2^64 to 2^64-1 inclusive. This means that we can have negative
integers that are bigger than the usual minimum. Internally we use i128 for the integers,
but we need to make sure that if integers encoded that they fall into the range CBOR
specifies. This commit introduces such a check.

Fixes #14.
  • Loading branch information
ruseinov authored Aug 25, 2023
1 parent 3795816 commit 94777d3
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 6 deletions.
11 changes: 11 additions & 0 deletions src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,23 @@ impl<'a, W: enc::Write> serde::Serializer for &'a mut Serializer<W> {

#[inline]
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
if !(u64::MAX as i128 >= v && -(u64::MAX as i128) <= v) {
return Err(EncodeError::Msg(
"Integer must be within [-u64::MAX, u64::MAX] range".into(),
));
}

v.encode(&mut self.writer)?;
Ok(())
}

#[inline]
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
if (u64::MAX as u128) < v {
return Err(EncodeError::Msg(
"Unsigned integer must be within [0, u64::MAX] range".into(),
));
}
v.encode(&mut self.writer)?;
Ok(())
}
Expand Down
13 changes: 13 additions & 0 deletions tests/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ fn test_integer() {
// u64
let vec = to_vec(&::std::u64::MAX).unwrap();
assert_eq!(vec, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff");
// u128 within u64 range
let vec = to_vec(&(u64::MAX as u128)).unwrap();
assert_eq!(vec, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff");
// u128 out of range
assert!(to_vec(&(u64::MAX as u128 + 1)).is_err());
// i128 within u64 range
let vec = to_vec(&(u64::MAX as i128)).unwrap();
assert_eq!(vec, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff");
// i128 within -u64 range
let vec = to_vec(&(-(u64::MAX as i128))).unwrap();
assert_eq!(vec, b"\x3B\xff\xff\xff\xff\xff\xff\xff\xfe");
// i128 out of -u64 range
assert!(to_vec(&(-(u64::MAX as i128) - 1)).is_err());
}

#[test]
Expand Down
6 changes: 0 additions & 6 deletions tests/std_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,4 @@ testcase!(
"a165416c706861821a00039447183c"
);
testcase!(test_i128_a, i128, -1i128, "20");
testcase!(
test_i128_b,
i128,
-18446744073709551616i128,
"3BFFFFFFFFFFFFFFFF"
);
testcase!(test_u128, u128, 17, "11");

0 comments on commit 94777d3

Please sign in to comment.