changeset 24255:4283c4c2fcb6 stable

Fix segfault with CHOLMOD library and empty matrices (bug #52365). * dSparse.cc, CSparse.cc (fsolve): Verify data() pointer to sparse matrix elements is not a nullptr. If it is, replace with a pointer to a valid memory location (local temporary variable on the stack).
author Rik <rik@octave.org>
date Wed, 15 Nov 2017 15:21:45 -0800
parents d2cfaaa57677
children b8e0bd54a268 bffbc95fa72b
files liboctave/array/CSparse.cc liboctave/array/dSparse.cc
diffstat 2 files changed, 36 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/array/CSparse.cc	Wed Nov 08 15:58:53 2017 -0500
+++ b/liboctave/array/CSparse.cc	Wed Nov 15 15:21:45 2017 -0800
@@ -5566,10 +5566,9 @@
           A->stype = 1;
           A->xtype = CHOLMOD_COMPLEX;
 
-          if (nr < 1)
+          A->x = data ();
+          if (A->x == 0)
             A->x = &dummy;
-          else
-            A->x = data ();
 
           cholmod_dense Bstore;
           cholmod_dense *B = &Bstore;
@@ -5579,11 +5578,10 @@
           B->nzmax = B->nrow * B->ncol;
           B->dtype = CHOLMOD_DOUBLE;
           B->xtype = CHOLMOD_REAL;
-          if (nc < 1 || b.cols () < 1)
+
+          B->x = const_cast<double *>(b.fortran_vec ());
+          if (B->x == 0)
             B->x = &dummy;
-          else
-            // We won't alter it, honest :-)
-            B->x = const_cast<double *>(b.fortran_vec ());
 
           cholmod_factor *L;
           BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
@@ -5816,10 +5814,9 @@
           A->stype = 1;
           A->xtype = CHOLMOD_COMPLEX;
 
-          if (nr < 1)
+          A->x = data ();
+          if (A->x == 0)
             A->x = &dummy;
-          else
-            A->x = data ();
 
           cholmod_sparse Bstore;
           cholmod_sparse *B = &Bstore;
@@ -5840,10 +5837,9 @@
           B->stype = 0;
           B->xtype = CHOLMOD_REAL;
 
-          if (b.rows () < 1 || b.cols () < 1)
+          B->x = b.data ();
+          if (B->x == 0)
             B->x = &dummy;
-          else
-            B->x = b.data ();
 
           cholmod_factor *L;
           BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
@@ -6114,10 +6110,9 @@
           A->stype = 1;
           A->xtype = CHOLMOD_COMPLEX;
 
-          if (nr < 1)
+          A->x = data ();
+          if (A->x == 0)
             A->x = &dummy;
-          else
-            A->x = data ();
 
           cholmod_dense Bstore;
           cholmod_dense *B = &Bstore;
@@ -6127,11 +6122,10 @@
           B->nzmax = B->nrow * B->ncol;
           B->dtype = CHOLMOD_DOUBLE;
           B->xtype = CHOLMOD_COMPLEX;
-          if (nc < 1 || b.cols () < 1)
+
+          B->x = const_cast<Complex *>(b.fortran_vec ());
+          if (B->x == 0)
             B->x = &dummy;
-          else
-            // We won't alter it, honest :-)
-            B->x = const_cast<Complex *>(b.fortran_vec ());
 
           cholmod_factor *L;
           BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
@@ -6343,10 +6337,9 @@
           A->stype = 1;
           A->xtype = CHOLMOD_COMPLEX;
 
-          if (nr < 1)
+          A->x = data ();
+          if (A->x == 0)
             A->x = &dummy;
-          else
-            A->x = data ();
 
           cholmod_sparse Bstore;
           cholmod_sparse *B = &Bstore;
@@ -6367,10 +6360,9 @@
           B->stype = 0;
           B->xtype = CHOLMOD_COMPLEX;
 
-          if (b.rows () < 1 || b.cols () < 1)
+          B->x = b.data ();
+          if (B->x == 0)
             B->x = &dummy;
-          else
-            B->x = b.data ();
 
           cholmod_factor *L;
           BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
--- a/liboctave/array/dSparse.cc	Wed Nov 08 15:58:53 2017 -0500
+++ b/liboctave/array/dSparse.cc	Wed Nov 15 15:21:45 2017 -0800
@@ -5739,10 +5739,9 @@
           A->stype = 1;
           A->xtype = CHOLMOD_REAL;
 
-          if (nr < 1)
+          A->x = data ();
+          if (A->x == 0)
             A->x = &dummy;
-          else
-            A->x = data ();
 
           cholmod_dense Bstore;
           cholmod_dense *B = &Bstore;
@@ -5752,11 +5751,10 @@
           B->nzmax = B->nrow * B->ncol;
           B->dtype = CHOLMOD_DOUBLE;
           B->xtype = CHOLMOD_REAL;
-          if (nc < 1 || b.cols () < 1)
+
+          B->x = const_cast<double *>(b.fortran_vec ());
+          if (B->x == 0)
             B->x = &dummy;
-          else
-            // We won't alter it, honest :-)
-            B->x = const_cast<double *>(b.fortran_vec ());
 
           cholmod_factor *L;
           BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
@@ -5963,10 +5961,9 @@
           A->stype = 1;
           A->xtype = CHOLMOD_REAL;
 
-          if (nr < 1)
+          A->x = data ();
+          if (A->x == 0)
             A->x = &dummy;
-          else
-            A->x = data ();
 
           cholmod_sparse Bstore;
           cholmod_sparse *B = &Bstore;
@@ -5987,10 +5984,9 @@
           B->stype = 0;
           B->xtype = CHOLMOD_REAL;
 
-          if (b.rows () < 1 || b.cols () < 1)
+          B->x = b.data ();
+          if (B->x == 0)
             B->x = &dummy;
-          else
-            B->x = b.data ();
 
           cholmod_factor *L;
           BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
@@ -6232,10 +6228,9 @@
           A->stype = 1;
           A->xtype = CHOLMOD_REAL;
 
-          if (nr < 1)
+          A->x = data ();
+          if (A->x == 0)
             A->x = &dummy;
-          else
-            A->x = data ();
 
           cholmod_dense Bstore;
           cholmod_dense *B = &Bstore;
@@ -6245,11 +6240,10 @@
           B->nzmax = B->nrow * B->ncol;
           B->dtype = CHOLMOD_DOUBLE;
           B->xtype = CHOLMOD_COMPLEX;
-          if (nc < 1 || b.cols () < 1)
+
+          B->x = const_cast<Complex *>(b.fortran_vec ());
+          if (B->x == 0)
             B->x = &dummy;
-          else
-            // We won't alter it, honest :-)
-            B->x = const_cast<Complex *>(b.fortran_vec ());
 
           cholmod_factor *L;
           BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
@@ -6473,10 +6467,9 @@
           A->stype = 1;
           A->xtype = CHOLMOD_REAL;
 
-          if (nr < 1)
+          A->x = data ();
+          if (A->x == 0)
             A->x = &dummy;
-          else
-            A->x = data ();
 
           cholmod_sparse Bstore;
           cholmod_sparse *B = &Bstore;
@@ -6497,10 +6490,9 @@
           B->stype = 0;
           B->xtype = CHOLMOD_COMPLEX;
 
-          if (b.rows () < 1 || b.cols () < 1)
+          B->x = b.data ();
+          if (B->x == 0)
             B->x = &dummy;
-          else
-            B->x = b.data ();
 
           cholmod_factor *L;
           BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;