Skip to content

Commit 06b03f7

Browse files
authored
Merge pull request #151 from reem/partial_cmp
Fix soundness bug in NotNan::partial_cmp.
2 parents 8eb3455 + 2f67d25 commit 06b03f7

File tree

2 files changed

+28
-29
lines changed

2 files changed

+28
-29
lines changed

src/lib.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use core::cmp::Ordering;
1515
use core::convert::TryFrom;
1616
use core::fmt;
1717
use core::hash::{Hash, Hasher};
18-
use core::hint::unreachable_unchecked;
1918
use core::iter::{Product, Sum};
2019
use core::num::FpCategory;
2120
use core::ops::{
@@ -1163,10 +1162,10 @@ impl Borrow<f64> for NotNan<f64> {
11631162
#[allow(clippy::derive_ord_xor_partial_ord)]
11641163
impl<T: FloatCore> Ord for NotNan<T> {
11651164
fn cmp(&self, other: &NotNan<T>) -> Ordering {
1166-
match self.partial_cmp(other) {
1167-
Some(ord) => ord,
1168-
None => unsafe { unreachable_unchecked() },
1169-
}
1165+
// Can't use unreachable_unchecked because unsafe code can't depend on FloatCore impl.
1166+
// https://github.com/reem/rust-ordered-float/issues/150
1167+
self.partial_cmp(other)
1168+
.expect("partial_cmp failed for non-NaN value")
11701169
}
11711170
}
11721171

@@ -2535,7 +2534,7 @@ mod impl_rand {
25352534
fn uniform_sampling_panic_on_infinity_notnan() {
25362535
let (low, high) = (
25372536
NotNan::new(0f64).unwrap(),
2538-
NotNan::new(core::f64::INFINITY).unwrap(),
2537+
NotNan::new(f64::INFINITY).unwrap(),
25392538
);
25402539
let uniform = Uniform::new(low, high);
25412540
let _ = uniform.sample(&mut rand::thread_rng());
@@ -2544,15 +2543,15 @@ mod impl_rand {
25442543
#[test]
25452544
#[should_panic]
25462545
fn uniform_sampling_panic_on_infinity_ordered() {
2547-
let (low, high) = (OrderedFloat(0f64), OrderedFloat(core::f64::INFINITY));
2546+
let (low, high) = (OrderedFloat(0f64), OrderedFloat(f64::INFINITY));
25482547
let uniform = Uniform::new(low, high);
25492548
let _ = uniform.sample(&mut rand::thread_rng());
25502549
}
25512550

25522551
#[test]
25532552
#[should_panic]
25542553
fn uniform_sampling_panic_on_nan_ordered() {
2555-
let (low, high) = (OrderedFloat(0f64), OrderedFloat(core::f64::NAN));
2554+
let (low, high) = (OrderedFloat(0f64), OrderedFloat(f64::NAN));
25562555
let uniform = Uniform::new(low, high);
25572556
let _ = uniform.sample(&mut rand::thread_rng());
25582557
}

tests/test.rs

+21-21
Original file line numberDiff line numberDiff line change
@@ -576,72 +576,72 @@ fn hash_is_good_for_fractional_numbers() {
576576
#[test]
577577
#[should_panic]
578578
fn test_add_fails_on_nan() {
579-
let a = not_nan(std::f32::INFINITY);
580-
let b = not_nan(std::f32::NEG_INFINITY);
579+
let a = not_nan(f32::INFINITY);
580+
let b = not_nan(f32::NEG_INFINITY);
581581
let _c = a + b;
582582
}
583583

584584
#[test]
585585
#[should_panic]
586586
fn test_add_fails_on_nan_ref() {
587-
let a = not_nan(std::f32::INFINITY);
588-
let b = not_nan(std::f32::NEG_INFINITY);
587+
let a = not_nan(f32::INFINITY);
588+
let b = not_nan(f32::NEG_INFINITY);
589589
let _c = a + &b;
590590
}
591591

592592
#[test]
593593
#[should_panic]
594594
fn test_add_fails_on_nan_ref_ref() {
595-
let a = not_nan(std::f32::INFINITY);
596-
let b = not_nan(std::f32::NEG_INFINITY);
595+
let a = not_nan(f32::INFINITY);
596+
let b = not_nan(f32::NEG_INFINITY);
597597
let _c = &a + &b;
598598
}
599599

600600
#[test]
601601
#[should_panic]
602602
fn test_add_fails_on_nan_t_ref() {
603-
let a = not_nan(std::f32::INFINITY);
604-
let b = std::f32::NEG_INFINITY;
603+
let a = not_nan(f32::INFINITY);
604+
let b = f32::NEG_INFINITY;
605605
let _c = a + &b;
606606
}
607607

608608
#[test]
609609
#[should_panic]
610610
fn test_add_fails_on_nan_ref_t_ref() {
611-
let a = not_nan(std::f32::INFINITY);
612-
let b = std::f32::NEG_INFINITY;
611+
let a = not_nan(f32::INFINITY);
612+
let b = f32::NEG_INFINITY;
613613
let _c = &a + &b;
614614
}
615615

616616
#[test]
617617
#[should_panic]
618618
fn test_add_fails_on_nan_ref_t() {
619-
let a = not_nan(std::f32::INFINITY);
620-
let b = std::f32::NEG_INFINITY;
619+
let a = not_nan(f32::INFINITY);
620+
let b = f32::NEG_INFINITY;
621621
let _c = &a + b;
622622
}
623623

624624
#[test]
625625
#[should_panic]
626626
fn test_add_assign_fails_on_nan_ref() {
627-
let mut a = not_nan(std::f32::INFINITY);
628-
let b = not_nan(std::f32::NEG_INFINITY);
627+
let mut a = not_nan(f32::INFINITY);
628+
let b = not_nan(f32::NEG_INFINITY);
629629
a += &b;
630630
}
631631

632632
#[test]
633633
#[should_panic]
634634
fn test_add_assign_fails_on_nan_t_ref() {
635-
let mut a = not_nan(std::f32::INFINITY);
636-
let b = std::f32::NEG_INFINITY;
635+
let mut a = not_nan(f32::INFINITY);
636+
let b = f32::NEG_INFINITY;
637637
a += &b;
638638
}
639639

640640
#[test]
641641
#[should_panic]
642642
fn test_add_assign_fails_on_nan_t() {
643-
let mut a = not_nan(std::f32::INFINITY);
644-
let b = std::f32::NEG_INFINITY;
643+
let mut a = not_nan(f32::INFINITY);
644+
let b = f32::NEG_INFINITY;
645645
a += b;
646646
}
647647

@@ -678,15 +678,15 @@ fn ordered_f64_neg() {
678678
#[test]
679679
#[should_panic]
680680
fn test_sum_fails_on_nan() {
681-
let a = not_nan(std::f32::INFINITY);
682-
let b = not_nan(std::f32::NEG_INFINITY);
681+
let a = not_nan(f32::INFINITY);
682+
let b = not_nan(f32::NEG_INFINITY);
683683
let _c: NotNan<_> = [a, b].iter().sum();
684684
}
685685

686686
#[test]
687687
#[should_panic]
688688
fn test_product_fails_on_nan() {
689-
let a = not_nan(std::f32::INFINITY);
689+
let a = not_nan(f32::INFINITY);
690690
let b = not_nan(0f32);
691691
let _c: NotNan<_> = [a, b].iter().product();
692692
}

0 commit comments

Comments
 (0)