Skip to content

Commit

Permalink
Fix issue with negative nanos in Duration::try_from(), and add tests (#…
Browse files Browse the repository at this point in the history
…803)

* Fix issue with negative nanos in Duration::try_from(), and add a unit test

* add proptest for negative nanos

* PR comment: remove spurious dbg
  • Loading branch information
danielsn authored Feb 2, 2023
1 parent 963a2cf commit c00da0b
Showing 1 changed file with 46 additions and 1 deletion.
47 changes: 46 additions & 1 deletion prost-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl TryFrom<Duration> for time::Duration {
/// Converts a `Duration` to a `std::time::Duration`, failing if the duration is negative.
fn try_from(mut duration: Duration) -> Result<time::Duration, DurationError> {
duration.normalize();
if duration.seconds >= 0 {
if duration.seconds >= 0 && duration.nanos >= 0 {
Ok(time::Duration::new(
duration.seconds as u64,
duration.nanos as u32,
Expand Down Expand Up @@ -454,6 +454,51 @@ mod tests {
)
}
}

#[test]
fn check_duration_roundtrip_nanos(
nanos in u32::arbitrary(),
) {
let seconds = 0;
let std_duration = std::time::Duration::new(seconds, nanos);
let prost_duration = match Duration::try_from(std_duration) {
Ok(duration) => duration,
Err(_) => return Err(TestCaseError::reject("duration out of range")),
};
prop_assert_eq!(time::Duration::try_from(prost_duration.clone()).unwrap(), std_duration);

if std_duration != time::Duration::default() {
let neg_prost_duration = Duration {
seconds: -prost_duration.seconds,
nanos: -prost_duration.nanos,
};

prop_assert!(
matches!(
time::Duration::try_from(neg_prost_duration),
Err(DurationError::NegativeDuration(d)) if d == std_duration,
)
)
}
}
}

#[cfg(feature = "std")]
#[test]
fn check_duration_try_from_negative_nanos() {
let seconds: u64 = 0;
let nanos: u32 = 1;
let std_duration = std::time::Duration::new(seconds, nanos);

let neg_prost_duration = Duration {
seconds: 0,
nanos: -1,
};

assert!(matches!(
time::Duration::try_from(neg_prost_duration),
Err(DurationError::NegativeDuration(d)) if d == std_duration,
))
}

#[cfg(feature = "std")]
Expand Down

0 comments on commit c00da0b

Please sign in to comment.