Mercurial > octave
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; }