Merge rust-bitcoin/rust-bitcoin#3052: Throw error instead of panic when from_second_ceil input is too large

7874db8fc3 Throw error instead of panic when from_second_ceil input is too large (Shing Him Ng)

Pull request description:

  Update `from_second_ceil` per [comment](https://github.com/rust-bitcoin/rust-bitcoin/issues/3029#issuecomment-2227459248) and add unit tests

  Resolves #3029

ACKs for top commit:
  Kixunil:
    ACK 7874db8fc3
  tcharding:
    ACK 7874db8fc3

Tree-SHA512: 0d60397f867d4536ff00b81441c27ea3dc4bf9e5ecc2fb5afbe50cb3153101df54c2bb5056da1916d83c3e84367f987f5bac07a381b7433a5701a0ea8a587f95
This commit is contained in:
merge-script 2024-07-16 13:36:23 +00:00
commit f765deb160
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 29 additions and 2 deletions

View File

@ -96,8 +96,8 @@ impl Time {
#[inline] #[inline]
#[rustfmt::skip] // moves comments to unrelated code #[rustfmt::skip] // moves comments to unrelated code
pub const fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> { pub const fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> {
if seconds <= u16::MAX as u32 * 512 {
let interval = (seconds + 511) / 512; let interval = (seconds + 511) / 512;
if interval <= u16::MAX as u32 { // infallible cast, needed by const code
Ok(Time::from_512_second_intervals(interval as u16)) // cast checked above, needed by const code Ok(Time::from_512_second_intervals(interval as u16)) // cast checked above, needed by const code
} else { } else {
Err(TimeOverflowError { seconds }) Err(TimeOverflowError { seconds })
@ -152,3 +152,30 @@ impl fmt::Display for TimeOverflowError {
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl std::error::Error for TimeOverflowError {} impl std::error::Error for TimeOverflowError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_seconds_ceil_success() {
let actual = Time::from_seconds_ceil(100).unwrap();
let expected = Time(1_u16);
assert_eq!(actual, expected);
}
#[test]
fn from_seconds_ceil_with_maximum_encodable_seconds_success() {
let maximum_encodable_seconds = u16::MAX as u32 * 512;
let actual = Time::from_seconds_ceil(maximum_encodable_seconds).unwrap();
let expected = Time(u16::MAX);
assert_eq!(actual, expected);
}
#[test]
fn from_seconds_ceil_causes_time_overflow_error() {
let maximum_encodable_seconds = u16::MAX as u32 * 512;
let result = Time::from_seconds_ceil(maximum_encodable_seconds + 1);
assert!(result.is_err());
}
}