diff libinterp/corefcn/__ichol__.cc @ 23899:437ba51e8bcf stable

Fix segfault in ichol under certain conditions (bug #51736). * __ichol__.cc (ichol_t): New variable std::vector<bool> mark to record whether column has been processed. Test whether column has already been processed before beginning operations.
author Richard Zweig <richard.zweig@gmx.de>
date Sat, 12 Aug 2017 02:23:56 +0200
parents 3ac9f9ecfae5
children 5621aae74d1a
line wrap: on
line diff
--- a/libinterp/corefcn/__ichol__.cc	Mon Aug 07 08:19:28 2017 -0700
+++ b/libinterp/corefcn/__ichol__.cc	Sat Aug 12 02:23:56 2017 +0200
@@ -258,8 +258,8 @@
   OCTAVE_LOCAL_BUFFER (octave_idx_type, Lfirst, n);
   OCTAVE_LOCAL_BUFFER (octave_idx_type, Llist, n);
   OCTAVE_LOCAL_BUFFER (T, col_drops, n);
-  std::vector <octave_idx_type> vec;
-  vec.resize (n);
+  std::vector<octave_idx_type> vec (n, 0);
+  std::vector<bool> mark (n, false);
 
   T zero = T (0);
   cidx_l[0] = cidx[0];
@@ -269,7 +269,6 @@
       Lfirst[i] = -1;
       w_data[i] = 0;
       col_drops[i] = zero;
-      vec[i] = 0;
     }
 
   total_len = 0;
@@ -279,6 +278,9 @@
       for (j = cidx[k]; j < cidx[k+1]; j++)
         {
           w_data[ridx[j]] = data[j];
+          // Mark column index, intentionally outside the if-clause to ensure
+          // that mark[k] will be set to true as well.
+          mark[ridx[j]] = true;
           if (ridx[j] != k)
             {
               vec[ind] = ridx[j];
@@ -296,8 +298,9 @@
               // If the element in the j position of the row is zero,
               // then it will become non-zero, so we add it to the
               // vector that tracks non-zero elements in the working row.
-              if (w_data[j] == zero)
+              if (! mark[j])
                 {
+                  mark[j] = true;
                   vec[ind] = j;
                   ind++;
                 }
@@ -359,8 +362,10 @@
                   ridx_l[total_len + w_len] = jrow;
                   w_len++;
                 }
-              vec[i] = 0;
             }
+          // Clear mark, vec, and w_data.  However, mark[k] is not set to zero.
+          mark[jrow] = false;
+          vec[i] = 0;
           w_data[jrow] = zero;
         }