mirror of https://git.sr.ht/~stygianentity/bincode
Fix overflow error when deserializing invalid Duration (#465)
* Fix overflow error when deserializing invalid Duration * Use unwrap_err instead of match in test
This commit is contained in:
parent
a08e528cc7
commit
236d350f13
|
|
@ -548,8 +548,12 @@ where
|
||||||
|
|
||||||
impl Decode for Duration {
|
impl Decode for Duration {
|
||||||
fn decode<D: Decoder>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decoder>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
let secs = Decode::decode(&mut decoder)?;
|
const NANOS_PER_SEC: u64 = 1_000_000_000;
|
||||||
let nanos = Decode::decode(&mut decoder)?;
|
let secs: u64 = Decode::decode(&mut decoder)?;
|
||||||
|
let nanos: u32 = Decode::decode(&mut decoder)?;
|
||||||
|
if secs.checked_add(u64::from(nanos) / NANOS_PER_SEC).is_none() {
|
||||||
|
return Err(DecodeError::InvalidDuration { secs, nanos });
|
||||||
|
}
|
||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/error.rs
10
src/error.rs
|
|
@ -122,6 +122,16 @@ pub enum DecodeError {
|
||||||
type_name: &'static str,
|
type_name: &'static str,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// The decoder tried to decode a Duration and overflowed the number of seconds.
|
||||||
|
InvalidDuration {
|
||||||
|
/// The number of seconds in the duration.
|
||||||
|
secs: u64,
|
||||||
|
|
||||||
|
/// The number of nanoseconds in the duration, which when converted to seconds and added to
|
||||||
|
/// `secs`, overflows a `u64`.
|
||||||
|
nanos: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// The decoder tried to decode a `CStr` or `CString`, but the incoming data contained a 0 byte
|
/// The decoder tried to decode a `CStr` or `CString`, but the incoming data contained a 0 byte
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
CStrNulError {
|
CStrNulError {
|
||||||
|
|
|
||||||
|
|
@ -219,3 +219,41 @@ fn test_array() {
|
||||||
assert_eq!(input, output);
|
assert_eq!(input, output);
|
||||||
assert_eq!(len, 10);
|
assert_eq!(len, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_duration_out_of_range() {
|
||||||
|
let mut input = [0u8; 14];
|
||||||
|
|
||||||
|
bincode::encode_into_slice(&(u64::MAX, u32::MAX), &mut input, Configuration::standard())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let result: Result<(std::time::Duration, usize), _> =
|
||||||
|
bincode::decode_from_slice(&mut input, Configuration::standard());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
result.unwrap_err(),
|
||||||
|
bincode::error::DecodeError::InvalidDuration {
|
||||||
|
secs: u64::MAX,
|
||||||
|
nanos: u32::MAX
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_duration_wrapping() {
|
||||||
|
let mut input = [0u8; 14];
|
||||||
|
|
||||||
|
bincode::encode_into_slice(
|
||||||
|
&(u64::MAX - 4, u32::MAX),
|
||||||
|
&mut input,
|
||||||
|
Configuration::standard(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let (result, _): (std::time::Duration, _) =
|
||||||
|
bincode::decode_from_slice(&mut input, Configuration::standard()).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(result.as_secs(), u64::MAX);
|
||||||
|
|
||||||
|
assert_eq!(result.subsec_nanos(), 294967295);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue