fix: avoid no_std panic in ceil helpers on non-finite input
Byte::from_f64/from_f32 let +inf past the size >= 0.0 guard and then called the no_std ceil helpers, which used Decimal::from_f64(v).unwrap(). Decimal conversion returns None for non-finite values, so this panicked in no_std builds while std returned None. Fall back to the input value for non-finite input so no_std matches std and the documented None contract is upheld.
This commit is contained in:
1 parent
600cbe8696
commit
ec58c32a8a
2 files changed
+21
-2
No files matched your search
+12
-2
@@ -36,7 +36,12 @@ pub(crate) fn ceil_f64(v: f64) -> f64 {
|
|||||||
pub(crate) fn ceil_f64(v: f64) -> f64 {
|
pub(crate) fn ceil_f64(v: f64) -> f64 {
|
||||||
debug_assert!(v >= 0.0);
|
debug_assert!(v >= 0.0);
|
||||||
|
|
||||||
Decimal::from_f64(v).unwrap().ceil().to_f64().unwrap()
|
// `Decimal::from_f64` returns `None` for non-finite values, so fall back to
|
||||||
|
// the input and mirror `f64::ceil` instead of panicking.
|
||||||
|
match Decimal::from_f64(v) {
|
||||||
|
Some(d) => d.ceil().to_f64().unwrap_or(v),
|
||||||
|
None => v,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "byte", feature = "bit"))]
|
#[cfg(any(feature = "byte", feature = "bit"))]
|
||||||
@@ -54,7 +59,12 @@ pub(crate) fn ceil_f32(v: f32) -> f32 {
|
|||||||
pub(crate) fn ceil_f32(v: f32) -> f32 {
|
pub(crate) fn ceil_f32(v: f32) -> f32 {
|
||||||
debug_assert!(v >= 0.0);
|
debug_assert!(v >= 0.0);
|
||||||
|
|
||||||
Decimal::from_f32(v).unwrap().ceil().to_f32().unwrap()
|
// `Decimal::from_f32` returns `None` for non-finite values, so fall back to
|
||||||
|
// the input and mirror `f32::ceil` instead of panicking.
|
||||||
|
match Decimal::from_f32(v) {
|
||||||
|
Some(d) => d.ceil().to_f32().unwrap_or(v),
|
||||||
|
None => v,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "byte", feature = "bit"))]
|
#[cfg(any(feature = "byte", feature = "bit"))]
|
||||||
|
|||||||
@@ -170,3 +170,12 @@ fn tests() {
|
|||||||
assert_eq!(byte, serde_json::from_str::<Byte>(case.0).unwrap(), "{i}");
|
assert_eq!(byte, serde_json::from_str::<Byte>(case.0).unwrap(), "{i}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_non_finite_returns_none() {
|
||||||
|
// Non-finite inputs must return None instead of panicking, in both builds.
|
||||||
|
assert_eq!(Byte::from_f64(f64::INFINITY), None);
|
||||||
|
assert_eq!(Byte::from_f64(f64::NAN), None);
|
||||||
|
assert_eq!(Byte::from_f32(f32::INFINITY), None);
|
||||||
|
assert_eq!(Byte::from_f32(f32::NAN), None);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user