changeset 28849:8b0675c2cfe0

Add functions to check for integer overflow on multiplication (bug #59094). * liboctave/wrappers/intprops-wrappers.c, intprops-wrappers.h: New files with functions to wrap around gnulib macros. * liboctave/wrappers/module.mk: Add new files to lists. * bootstrap.conf: Add gnulib module "intprops". * liboctave/util/lo-utils.cc, lo-utils.h (int_multiply_overflow): Add new (overloaded) functions to check for integer overflow on multiplication. * libinterp/dldfcn/__ode15__.cc (IDA::set_up): Check if multiplication would overflow.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 19 Sep 2020 12:09:57 +0200
parents 751afb1ee1d0
children 445e5ac1f58d
files bootstrap.conf libinterp/dldfcn/__ode15__.cc liboctave/util/lo-utils.cc liboctave/util/lo-utils.h liboctave/wrappers/intprops-wrappers.c liboctave/wrappers/intprops-wrappers.h liboctave/wrappers/module.mk
diffstat 7 files changed, 199 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/bootstrap.conf	Wed Sep 30 17:18:50 2020 -0400
+++ b/bootstrap.conf	Sat Sep 19 12:09:57 2020 +0200
@@ -56,6 +56,7 @@
   getrusage
   gettimeofday
   glob
+  intprops
   isatty
   largefile
   link
--- a/libinterp/dldfcn/__ode15__.cc	Wed Sep 30 17:18:50 2020 -0400
+++ b/libinterp/dldfcn/__ode15__.cc	Sat Sep 19 12:09:57 2020 +0200
@@ -31,6 +31,7 @@
 #include "dMatrix.h"
 #include "dSparse.h"
 #include "f77-fcn.h"
+#include "lo-utils.h"
 
 #include "Cell.h"
 #include "defun-dld.h"
@@ -401,9 +402,9 @@
         // entries.
         m_sunJacMatrix = SUNSparseMatrix (m_num, m_num, 0, CSC_MAT);
 #    else
-        // FIXME: m_num*m_num might be larger than the largest
-        // octave_f77_int_type (integer overflow).  Consider using a save
-        // calculation method.
+        if (octave::math::int_multiply_overflow (m_num, m_num))
+          error ("Unable to allocate memory for sparse Jacobian");
+
         m_sunJacMatrix = SUNSparseMatrix (m_num, m_num, m_num*m_num, CSC_MAT);
 #    endif
         if (! m_sunJacMatrix)
--- a/liboctave/util/lo-utils.cc	Wed Sep 30 17:18:50 2020 -0400
+++ b/liboctave/util/lo-utils.cc	Sat Sep 19 12:09:57 2020 +0200
@@ -38,6 +38,7 @@
 
 #include "quit.h"
 
+#include "intprops-wrappers.h"
 #include "lo-error.h"
 #include "lo-ieee.h"
 #include "lo-mappers.h"
@@ -424,4 +425,43 @@
     write_value<float> (os, imag (value));
     os << ')';
   }
+
+  namespace math
+  {
+    bool int_multiply_overflow (int a, int b)
+    {
+      return octave_i_multiply_overflow_wrapper (a, b);
+    }
+
+    bool int_multiply_overflow (long int a, long int b)
+    {
+      return octave_li_multiply_overflow_wrapper (a, b);
+    }
+
+#if defined (OCTAVE_HAVE_LONG_LONG_INT)
+    bool int_multiply_overflow (long long int a, long long int b)
+    {
+      return octave_lli_multiply_overflow_wrapper (a, b);
+    }
+#endif
+
+    bool int_multiply_overflow (unsigned int a, unsigned int b)
+    {
+      return octave_ui_multiply_overflow_wrapper (a, b);
+    }
+
+    bool int_multiply_overflow (unsigned long int a, unsigned long int b)
+    {
+      return octave_uli_multiply_overflow_wrapper (a, b);
+    }
+
+#if defined (OCTAVE_HAVE_UNSIGNED_LONG_LONG_INT)
+    bool int_multiply_overflow (unsigned long long int a,
+                                unsigned long long int b)
+    {
+      return octave_ulli_multiply_overflow_wrapper (a, b);
+    }
+#endif
+
+  }
 }
--- a/liboctave/util/lo-utils.h	Wed Sep 30 17:18:50 2020 -0400
+++ b/liboctave/util/lo-utils.h	Sat Sep 19 12:09:57 2020 +0200
@@ -123,6 +123,21 @@
   template <> void write_value (std::ostream& os, const Complex& value);
   template <> void write_value (std::ostream& os, const float& value);
   template <> void write_value (std::ostream& os, const FloatComplex& value);
+
+  namespace math
+  {
+    bool int_multiply_overflow (int a, int b);
+    bool int_multiply_overflow (long int a, long int b);
+#if defined (OCTAVE_HAVE_LONG_LONG_INT)
+    bool int_multiply_overflow (long long int a, long long int b);
+#endif
+    bool int_multiply_overflow (unsigned int a, unsigned int b);
+    bool int_multiply_overflow (unsigned long int a, unsigned long int b);
+#if defined (OCTAVE_HAVE_UNSIGNED_LONG_LONG_INT)
+    bool int_multiply_overflow (unsigned long long int a,
+                                unsigned long long int b);
+#endif
+  }
 }
 
 OCTAVE_DEPRECATED (7, "use 'octave::read_value<T>' instead")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/wrappers/intprops-wrappers.c	Sat Sep 19 12:09:57 2020 +0200
@@ -0,0 +1,75 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2020 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#include "intprops.h"
+
+#include "intprops-wrappers.h"
+
+// The *_OVERFLOW macros are provided by gnulib.  We don't include gnulib
+// headers directly in Octave's C++ source files to avoid problems that
+// may be caused by the way that gnulib overrides standard library
+// functions.
+
+int
+octave_i_multiply_overflow_wrapper (int a, int b)
+{
+  return INT_MULTIPLY_OVERFLOW (a, b);
+}
+
+int
+octave_li_multiply_overflow_wrapper (long int a, long int b)
+{
+  return INT_MULTIPLY_OVERFLOW (a, b);
+}
+
+#if defined (OCTAVE_HAVE_LONG_LONG_INT)
+int
+octave_lli_multiply_overflow_wrapper (long long int a, long long int b)
+{
+  return INT_MULTIPLY_OVERFLOW (a, b);
+}
+#endif
+
+int
+octave_ui_multiply_overflow_wrapper (unsigned int a, unsigned int b)
+{
+  return INT_MULTIPLY_OVERFLOW (a, b);
+}
+
+int
+octave_uli_multiply_overflow_wrapper (unsigned long int a,
+                                      unsigned long int b)
+{
+  return INT_MULTIPLY_OVERFLOW (a, b);
+}
+
+#if defined (OCTAVE_HAVE_UNSIGNED_LONG_LONG_INT)
+int
+octave_ulli_multiply_overflow_wrapper (unsigned long long int a,
+                                       unsigned long long int b)
+{
+  return INT_MULTIPLY_OVERFLOW (a, b);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/wrappers/intprops-wrappers.h	Sat Sep 19 12:09:57 2020 +0200
@@ -0,0 +1,62 @@
+////////////////////////////////////////////////////////////////////////
+//
+// Copyright (C) 2020 The Octave Project Developers
+//
+// See the file COPYRIGHT.md in the top-level directory of this
+// distribution or <https://octave.org/copyright/>.
+//
+// This file is part of Octave.
+//
+// Octave is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Octave is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Octave; see the file COPYING.  If not, see
+// <https://www.gnu.org/licenses/>.
+//
+////////////////////////////////////////////////////////////////////////
+
+#if ! defined (octave_localcharset_wrapper_h)
+#define octave_localcharset_wrapper_h 1
+
+#include "octave-config.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+// These functions return 1 if the operation between the input arguments would
+// overflow.
+
+extern int octave_i_multiply_overflow_wrapper (int a, int b);
+
+extern int octave_li_multiply_overflow_wrapper (long int a, long int b);
+
+#  if defined (OCTAVE_HAVE_LONG_LONG_INT)
+extern int octave_lli_multiply_overflow_wrapper (long long int a,
+                                                 long long int b);
+#  endif
+
+extern int octave_ui_multiply_overflow_wrapper (unsigned int a,
+                                                unsigned int b);
+
+extern int octave_uli_multiply_overflow_wrapper (unsigned long int a,
+                                                 unsigned long int b);
+
+#  if defined (OCTAVE_HAVE_UNSIGNED_LONG_LONG_INT)
+extern int octave_ulli_multiply_overflow_wrapper (unsigned long long int a,
+                                                  unsigned long long int b);
+#  endif
+
+#if defined __cplusplus
+}
+#endif
+
+#endif
--- a/liboctave/wrappers/module.mk	Wed Sep 30 17:18:50 2020 -0400
+++ b/liboctave/wrappers/module.mk	Sat Sep 19 12:09:57 2020 +0200
@@ -12,6 +12,7 @@
   %reldir%/glob-wrappers.h \
   %reldir%/hash-wrappers.h \
   %reldir%/iconv-wrappers.h \
+  %reldir%/intprops-wrappers.h \
   %reldir%/localcharset-wrapper.h \
   %reldir%/math-wrappers.h \
   %reldir%/mkostemp-wrapper.h \
@@ -54,6 +55,7 @@
   %reldir%/glob-wrappers.c \
   %reldir%/hash-wrappers.c \
   %reldir%/iconv-wrappers.c \
+  %reldir%/intprops-wrappers.c \
   %reldir%/localcharset-wrapper.c \
   %reldir%/math-wrappers.c \
   %reldir%/mkostemp-wrapper.c \