From b376198421cc2eecfa2f633659bb0edf682a6e19 Mon Sep 17 00:00:00 2001 From: LingMan Date: Tue, 16 Jun 2020 02:24:59 +0200 Subject: [PATCH 1/3] Fix c2c2c_identity test Reusing a plan for different arrays than it was created with requires that they have the same size and alignment as was used for creating the plan. While the size of `a` and `b` is identical, there is no such guarantee for their alignment. Therefore one may not simply swap them. Fix this by using separate plans for the `in: a, out: b` and `in: b, out: a` invocations. --- fftw/tests/c2c.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fftw/tests/c2c.rs b/fftw/tests/c2c.rs index 4a4c3e02..e5001050 100644 --- a/fftw/tests/c2c.rs +++ b/fftw/tests/c2c.rs @@ -8,13 +8,18 @@ fn c2c2c_identity() { let n = 32; let mut a = vec![c64::zero(); n]; let mut b = vec![c64::zero(); n]; - let mut plan: C2CPlan64 = + + let mut plan_ab: C2CPlan64 = C2CPlan::new(&[n], &mut a, &mut b, Sign::Forward, Flag::MEASURE).unwrap(); + let mut plan_ba: C2CPlan64 = + C2CPlan::new(&[n], &mut b, &mut a, Sign::Forward, Flag::MEASURE).unwrap(); + for i in 0..n { a[i] = c64::new(1.0, 0.0); } - plan.c2c(&mut a, &mut b).unwrap(); - plan.c2c(&mut b, &mut a).unwrap(); + + plan_ab.c2c(&mut a, &mut b).unwrap(); + plan_ba.c2c(&mut b, &mut a).unwrap(); for v in a.iter() { let ans = c64::new(n as f64, 0.0); let dif = (v - ans).norm(); From acdb2095f4b1ca42a79d243c9251333d1f2b19b0 Mon Sep 17 00:00:00 2001 From: LingMan Date: Tue, 16 Jun 2020 02:54:10 +0200 Subject: [PATCH 2/3] Fix r2r2r_identity test Reusing a plan for different arrays than it was created with requires that they have the same size and alignment as was used for creating the plan. By assigning an entirely new vec to `a` - which may have a different alignment - this test currently violating that requirement. Fix this by filling the existing vec instead of allocating a new one --- fftw/tests/r2r.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fftw/tests/r2r.rs b/fftw/tests/r2r.rs index 1161af4a..5ace2c9e 100644 --- a/fftw/tests/r2r.rs +++ b/fftw/tests/r2r.rs @@ -25,7 +25,9 @@ fn r2r2r_identity() { let factor = 2. * n as f64; // Vector of ones. - a = vec![1.0f64; n]; + for a_i in a.iter_mut() { + *a_i = 1.0; + } // Forward pass. fwd.r2r(&mut a, &mut b).unwrap(); From 93f96dcb2dc049bd724554cd3f9d23baebef6e07 Mon Sep 17 00:00:00 2001 From: LingMan Date: Sun, 7 Jun 2020 16:36:28 +0200 Subject: [PATCH 3/3] Validate input to C2CPlan::c2c and R2RPlan::r2r The underlying C function requires that the arrays passed into it have the same length and alignment as was used to create the plan. Adding this check prevents out-of-bounds reads and possibly writes. The same check is already in place for C2R and R2C plans. Fixes: https://github.com/rust-math/fftw/commit/3e84ddd4f7deb583ff4ca8b47ee266576021fac5 Fixes: https://github.com/rust-math/fftw/commit/862fead9b7e815c7914acccf50106702a89beaff --- fftw/src/plan.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fftw/src/plan.rs b/fftw/src/plan.rs index 21ad48e5..26342707 100644 --- a/fftw/src/plan.rs +++ b/fftw/src/plan.rs @@ -202,6 +202,7 @@ macro_rules! impl_c2c { }) } fn c2c(&mut self, in_: &mut [Self::Complex], out: &mut [Self::Complex]) -> Result<()> { + self.check(in_, out)?; unsafe { $exec(self.plan, in_.as_mut_ptr(), out.as_mut_ptr()) }; Ok(()) } @@ -315,6 +316,7 @@ macro_rules! impl_r2r { }) } fn r2r(&mut self, in_: &mut [Self::Real], out: &mut [Self::Real]) -> Result<()> { + self.check(in_, out)?; unsafe { $exec(self.plan, in_.as_mut_ptr(), out.as_mut_ptr()) }; Ok(()) }