changeset 24035:bc0aa7e18c96

fix possible array bounds error when calculating inverse (bug #49235) * dMatrix.cc (Matrix::finverse): Double size of DGECON work array as required by the LAPACK documentation. Thanks to Dario Meluzzi for the suggestion. * fMatrix.cc (FloatMatrix::finverse): Likewise, for SGECON. Fix formatting and local variable naming for consistency. * CMatrix.cc (ComplexMatrix::finverse): Fix formatting for consistency. * fCMatrix.cc (FloatComplexMatrix::finverse): Fix formatting and local variable naming for consistency.
author Mike Miller <mtmiller@octave.org>
date Wed, 13 Sep 2017 16:38:06 -0700
parents 18efaf716530
children 2932a325930c
files liboctave/array/CMatrix.cc liboctave/array/dMatrix.cc liboctave/array/fCMatrix.cc liboctave/array/fMatrix.cc
diffstat 4 files changed, 17 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/array/CMatrix.cc	Wed Sep 13 16:29:18 2017 -0700
+++ b/liboctave/array/CMatrix.cc	Wed Sep 13 16:38:06 2017 -0700
@@ -840,7 +840,7 @@
   info = tmp_info;
 
   lwork = static_cast<F77_INT> (std::real (z(0)));
-  lwork = (lwork <  2 *nc ? 2*nc : lwork);
+  lwork = (lwork < 2 * nc ? 2 * nc : lwork);
   z.resize (dim_vector (lwork, 1));
   Complex *pz = z.fortran_vec ();
 
@@ -869,8 +869,9 @@
     info = -1;
   else if (calc_cond)
     {
+      F77_INT zgecon_info = 0;
+
       // Now calculate the condition number for non-singular matrix.
-      F77_INT zgecon_info = 0;
       char job = '1';
       Array<double> rz (dim_vector (2 * nc, 1));
       double *prz = rz.fortran_vec ();
--- a/liboctave/array/dMatrix.cc	Wed Sep 13 16:29:18 2017 -0700
+++ b/liboctave/array/dMatrix.cc	Wed Sep 13 16:38:06 2017 -0700
@@ -549,8 +549,10 @@
   F77_XFCN (dgetri, DGETRI, (nc, tmp_data, nr, pipvt,
                              z.fortran_vec (), lwork, tmp_info));
 
+  info = tmp_info;
+
   lwork = static_cast<F77_INT> (z(0));
-  lwork = (lwork < 2 *nc ? 2*nc : lwork);
+  lwork = (lwork < 4 * nc ? 4 * nc : lwork);
   z.resize (dim_vector (lwork, 1));
   double *pz = z.fortran_vec ();
 
--- a/liboctave/array/fCMatrix.cc	Wed Sep 13 16:29:18 2017 -0700
+++ b/liboctave/array/fCMatrix.cc	Wed Sep 13 16:38:06 2017 -0700
@@ -843,7 +843,7 @@
   info = tmp_info;
 
   lwork = static_cast<F77_INT> (std::real (z(0)));
-  lwork = (lwork <  2 *nc ? 2*nc : lwork);
+  lwork = (lwork < 2 * nc ? 2 * nc : lwork);
   z.resize (dim_vector (lwork, 1));
   FloatComplex *pz = z.fortran_vec ();
 
@@ -871,17 +871,18 @@
     info = -1;
   else if (calc_cond)
     {
+      F77_INT cgecon_info = 0;
+
       // Now calculate the condition number for non-singular matrix.
-      F77_INT zgecon_info = 0;
       char job = '1';
       Array<float> rz (dim_vector (2 * nc, 1));
       float *prz = rz.fortran_vec ();
       F77_XFCN (cgecon, CGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
                                  nc, F77_CMPLX_ARG (tmp_data), nr, anorm,
-                                 rcon, F77_CMPLX_ARG (pz), prz, zgecon_info
+                                 rcon, F77_CMPLX_ARG (pz), prz, cgecon_info
                                  F77_CHAR_ARG_LEN (1)));
 
-      if (zgecon_info != 0)
+      if (cgecon_info != 0)
         info = -1;
     }
 
--- a/liboctave/array/fMatrix.cc	Wed Sep 13 16:29:18 2017 -0700
+++ b/liboctave/array/fMatrix.cc	Wed Sep 13 16:38:06 2017 -0700
@@ -546,7 +546,7 @@
   retval = *this;
   float *tmp_data = retval.fortran_vec ();
 
-  Array<float> z(dim_vector (1, 1));
+  Array<float> z (dim_vector (1, 1));
   F77_INT lwork = -1;
 
   F77_INT tmp_info = 0;
@@ -558,11 +558,12 @@
   info = tmp_info;
 
   lwork = static_cast<F77_INT> (z(0));
-  lwork = (lwork < 2 *nc ? 2*nc : lwork);
+  lwork = (lwork < 4 * nc ? 4 * nc : lwork);
   z.resize (dim_vector (lwork, 1));
   float *pz = z.fortran_vec ();
 
   info = 0;
+  tmp_info = 0;
 
   // Calculate the norm of the matrix, for later use.
   float anorm = 0;
@@ -580,7 +581,7 @@
     info = -1;
   else if (calc_cond)
     {
-      F77_INT dgecon_info = 0;
+      F77_INT sgecon_info = 0;
 
       // Now calculate the condition number for non-singular matrix.
       char job = '1';
@@ -588,10 +589,10 @@
       F77_INT *piz = iz.fortran_vec ();
       F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
                                  nc, tmp_data, nr, anorm,
-                                 rcon, pz, piz, dgecon_info
+                                 rcon, pz, piz, sgecon_info
                                  F77_CHAR_ARG_LEN (1)));
 
-      if (dgecon_info != 0)
+      if (sgecon_info != 0)
         info = -1;
     }