changeset 22662:655157b34a9f stable

Fix segfault when calling fft on last dimension (bug #49026). * fft.cc: New variable ndims to simplify code. Add FIXME about strange unnecessary input validation. Simplify code by using first_non_singleton() rather than hand-rolled for loop. Check for number of FFT points equal to 1 and execute special case which is simply indexing into the matrix. Change '%%' to '##' in BIST tests to follow Octave coding conventions.
author Rik <rik@octave.org>
date Fri, 21 Oct 2016 12:08:29 -0700
parents c00578ac8dda
children 9a939479308f a17848537a67
files libinterp/corefcn/fft.cc
diffstat 1 files changed, 32 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/fft.cc	Mon Oct 24 08:56:15 2016 -0700
+++ b/libinterp/corefcn/fft.cc	Fri Oct 21 12:08:29 2016 -0700
@@ -49,8 +49,9 @@
 
   octave_value retval;
   octave_value arg = args(0);
+  octave_idx_type n_points = -1;
   dim_vector dims = arg.dims ();
-  octave_idx_type n_points = -1;
+  int ndims = dims.ndims ();
   int dim = -1;
 
   if (nargin > 1)
@@ -72,7 +73,7 @@
       double dval = args(2).double_value ();
       if (octave::math::isnan (dval))
         error ("%s: DIM cannot be NaN", fcn);
-      else if (dval < 1 || dval > dims.ndims ())
+      else if (dval < 1 || dval > ndims)
         error ("%s: DIM must be a valid dimension along which to perform FFT",
                fcn);
       else
@@ -80,21 +81,19 @@
         dim = octave::math::nint (dval) - 1;
     }
 
-  for (octave_idx_type i = 0; i < dims.ndims (); i++)
+  // FIXME: This seems strange and unnecessary (10/21/16).
+  // How would you ever arrive at an octave_value object without correct dims?
+  // We certainly don't make this check every other place in Octave.
+  for (octave_idx_type i = 0; i < ndims; i++)
     if (dims(i) < 0)
       return retval;
 
   if (dim < 0)
     {
-      for (octave_idx_type i = 0; i < dims.ndims (); i++)
-        if (dims(i) > 1)
-          {
-            dim = i;
-            break;
-          }
+      dim = dims.first_non_singleton ();
 
       // And if the first argument is scalar?
-      if (dim < 0)
+      if (dim == ndims)
         dim = 1;
     }
 
@@ -103,7 +102,7 @@
   else
     dims(dim) = n_points;
 
-  if (dims.any_zero () || n_points == 0)
+  if (n_points == 0 || dims.any_zero ())
     {
       if (arg.is_single_type ())
         return octave_value (FloatNDArray (dims));
@@ -111,6 +110,16 @@
         return octave_value (NDArray (dims));
     }
 
+  if (n_points == 1)
+    {
+      octave_value_list idx (ndims);
+      for (octave_idx_type i = 0; i < ndims; i++)
+        idx(i) = idx_vector::colon;
+      idx(dim) = idx_vector (0);
+
+      return arg.do_index_op (idx);
+    }
+
   if (arg.is_single_type ())
     {
       if (arg.is_real_type ())
@@ -230,9 +239,9 @@
 }
 
 /*
-%% Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
-%%         Comalco Research and Technology
-%%         02 May 2000
+## Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
+##         Comalco Research and Technology
+##         02 May 2000
 %!test
 %! N = 64;
 %! n = 4;
@@ -246,9 +255,9 @@
 %!
 %! assert (S, answer, 4*N*eps);
 
-%% Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
-%%         Comalco Research and Technology
-%%         02 May 2000
+## Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
+##         Comalco Research and Technology
+##         02 May 2000
 %!test
 %! N = 64;
 %! n = 7;
@@ -261,9 +270,9 @@
 %!
 %! assert (ifft (S), s, 4*N*eps);
 
-%% Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
-%%         Comalco Research and Technology
-%%         02 May 2000
+## Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
+##         Comalco Research and Technology
+##         02 May 2000
 %!test
 %! N = 64;
 %! n = 4;
@@ -277,9 +286,9 @@
 %!
 %! assert (S, answer, 4*N*eps ("single"));
 
-%% Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
-%%         Comalco Research and Technology
-%%         02 May 2000
+## Author: David Billinghurst (David.Billinghurst@riotinto.com.au)
+##         Comalco Research and Technology
+##         02 May 2000
 %!test
 %! N = 64;
 %! n = 7;