Merge pull request #191 from m1el/fuzz-rem-overflows

Fixed a few int overflows
This commit is contained in:
Alex Crichton
2019-07-02 10:41:48 -05:00
committed by GitHub
3 changed files with 48 additions and 21 deletions
+34 -19
View File
@@ -179,29 +179,44 @@ pub(crate) fn rem_pio2(x: f64) -> (i32, f64, f64) {
i -= 1;
}
let mut ty = [0.0; 3];
let n = rem_pio2_large(&tx[..=i], &mut ty, ((ix >> 20) - (0x3ff + 23)) as i32, 1);
let n = rem_pio2_large(&tx[..=i], &mut ty, ((ix as i32) >> 20) - (0x3ff + 23), 1);
if sign != 0 {
return (-n, -ty[0], -ty[1]);
}
(n, ty[0], ty[1])
}
#[test]
fn test_near_pi() {
assert_eq!(
rem_pio2(3.141592025756836),
(2, -6.278329573009626e-7, -2.1125998133974653e-23)
);
assert_eq!(
rem_pio2(3.141592033207416),
(2, -6.20382377148128e-7, -2.1125998133974653e-23)
);
assert_eq!(
rem_pio2(3.141592144966125),
(2, -5.086236681942706e-7, -2.1125998133974653e-23)
);
assert_eq!(
rem_pio2(3.141592979431152),
(2, 3.2584135866119817e-7, -2.1125998133974653e-23)
);
#[cfg(test)]
mod tests {
use super::rem_pio2;
#[test]
fn test_near_pi() {
assert_eq!(
rem_pio2(3.141592025756836),
(2, -6.278329573009626e-7, -2.1125998133974653e-23)
);
assert_eq!(
rem_pio2(3.141592033207416),
(2, -6.20382377148128e-7, -2.1125998133974653e-23)
);
assert_eq!(
rem_pio2(3.141592144966125),
(2, -5.086236681942706e-7, -2.1125998133974653e-23)
);
assert_eq!(
rem_pio2(3.141592979431152),
(2, 3.2584135866119817e-7, -2.1125998133974653e-23)
);
}
#[test]
fn test_overflow_b9b847() {
let _ = rem_pio2(-3054214.5490637687);
}
#[test]
fn test_overflow_4747b9() {
let _ = rem_pio2(917340800458.2274);
}
}
+1 -1
View File
@@ -256,7 +256,7 @@ pub(crate) fn rem_pio2_large(x: &[f64], y: &mut [f64], e0: i32, prec: usize) ->
let jv = jv as usize;
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
let mut j = (jv - jx) as i32;
let mut j = (jv as i32) - (jx as i32);
let m = jx + jk;
for i in 0..=m {
i!(f, i, =, if j < 0 {
+13 -1
View File
@@ -85,7 +85,8 @@ pub fn remquo(mut x: f64, mut y: f64) -> (f64, i32) {
}
if ex == ey || (ex + 1 == ey && (2.0 * x > y || (2.0 * x == y && (q % 2) != 0))) {
x -= y;
q += 1;
// TODO: this matches musl behavior, but it is incorrect
q = q.wrapping_add(1);
}
q &= 0x7fffffff;
let quo = if sx ^ sy { -(q as i32) } else { q as i32 };
@@ -95,3 +96,14 @@ pub fn remquo(mut x: f64, mut y: f64) -> (f64, i32) {
(x, quo)
}
}
#[cfg(test)]
mod tests {
use super::remquo;
#[test]
fn test_q_overflow() {
// 0xc000000000000001, 0x04c0000000000004
let _ = remquo(-2.0000000000000004, 8.406091369059082e-286);
}
}