changeset 18691:9a6646cc7c3e

Fix load/save to handle up to 2^32-1 elements. Use std::streamsize in calculations of number of bytes, rather than octave_idx_type, so that expressions like 8 * nel do not overflow. * ls-mat4.cc (save_mat_binary_data): Use std::streamsize in calculations of number of bytes. * ls-mat5.cc (read_mat5_integer_data, MAT5_DO_WRITE): Use std::streamsize in calculations of number of bytes. * data-conv.cc (LS_DO_READ, LS_DO_READ, read_doubles, read_floats, write_floats): Use std::streamsize in calculations of number of bytes.
author Rik <rik@octave.org>
date Sun, 27 Apr 2014 17:38:03 -0700
parents 44f0d1a53ead
children fe0e34be5576
files libinterp/corefcn/ls-mat4.cc libinterp/corefcn/ls-mat5.cc liboctave/util/data-conv.cc
diffstat 3 files changed, 28 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/ls-mat4.cc	Sat Apr 26 16:39:20 2014 -0700
+++ b/libinterp/corefcn/ls-mat4.cc	Sun Apr 27 17:38:03 2014 -0700
@@ -461,7 +461,6 @@
       len = nr * nc;
     }
 
-
   // LEN includes the terminating character, and the file is also
   // supposed to include it.
 
@@ -489,7 +488,10 @@
           for (octave_idx_type j = 0; j < ncol; j++)
             buf[j*nrow+i] = static_cast<double> (*s++ & 0x00FF);
         }
-      os.write (reinterpret_cast<char *> (buf), nrow*ncol*sizeof (double));
+      std::streamsize n_bytes = static_cast<std::streamsize> (nrow) *
+                                static_cast<std::streamsize> (ncol) *
+                                sizeof (double);
+      os.write (reinterpret_cast<char *> (buf), n_bytes);
     }
   else if (tc.is_range ())
     {
@@ -518,7 +520,8 @@
 
           for (octave_idx_type i = 0; i < len; i++)
             dtmp[i] = m.ridx (i) + 1;
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = nr;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
@@ -526,19 +529,19 @@
           for (octave_idx_type j = 0; j < nc; j++)
             for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++)
               dtmp[ii++] = j + 1;
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = nc;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
           for (octave_idx_type i = 0; i < len; i++)
             dtmp[i] = std::real (m.data (i));
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = 0.;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
           for (octave_idx_type i = 0; i < len; i++)
             dtmp[i] = std::imag (m.data (i));
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           os.write (reinterpret_cast<const char *> (&ds), 8);
         }
       else
@@ -547,7 +550,8 @@
 
           for (octave_idx_type i = 0; i < len; i++)
             dtmp[i] = m.ridx (i) + 1;
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = nr;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
@@ -555,11 +559,11 @@
           for (octave_idx_type j = 0; j < nc; j++)
             for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++)
               dtmp[ii++] = j + 1;
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = nc;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
-          os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+          os.write (reinterpret_cast<const char *> (m.data ()), n_bytes);
           ds = 0.;
           os.write (reinterpret_cast<const char *> (&ds), 8);
         }
@@ -567,7 +571,8 @@
   else if (tc.is_real_matrix ())
     {
       Matrix m = tc.matrix_value ();
-      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+      std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
+      os.write (reinterpret_cast<const char *> (m.data ()), n_bytes);
     }
   else if (tc.is_complex_scalar ())
     {
@@ -578,9 +583,10 @@
     {
       ComplexMatrix m_cmplx = tc.complex_matrix_value ();
       Matrix m = ::real (m_cmplx);
-      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+      std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
+      os.write (reinterpret_cast<const char *> (m.data ()), n_bytes);
       m = ::imag (m_cmplx);
-      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+      os.write (reinterpret_cast<const char *> (m.data ()), n_bytes);
     }
   else
     gripe_wrong_type_arg ("save", tc, false);
--- a/libinterp/corefcn/ls-mat5.cc	Sat Apr 26 16:39:20 2014 -0700
+++ b/libinterp/corefcn/ls-mat5.cc	Sun Apr 27 17:38:03 2014 -0700
@@ -264,7 +264,8 @@
       if (len > 0) \
         { \
           OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
-          stream.read (reinterpret_cast<char *> (ptr), size * len); \
+          std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
+          stream.read (reinterpret_cast<char *> (ptr), n_bytes); \
           if (swap) \
             swap_bytes< size > (ptr, len); \
           for (octave_idx_type i = 0; i < len; i++) \
@@ -1667,7 +1668,8 @@
       OCTAVE_LOCAL_BUFFER (TYPE, ptr, count); \
       for (octave_idx_type i = 0; i < count; i++) \
         ptr[i] = static_cast<TYPE> (data[i]); \
-      stream.write (reinterpret_cast<char *> (ptr), count * sizeof (TYPE)); \
+      std::streamsize n_bytes = sizeof (TYPE) * static_cast<std::streamsize> (count); \
+      stream.write (reinterpret_cast<char *> (ptr), n_bytes); \
     } \
   while (0)
 
--- a/liboctave/util/data-conv.cc	Sat Apr 26 16:39:20 2014 -0700
+++ b/liboctave/util/data-conv.cc	Sun Apr 27 17:38:03 2014 -0700
@@ -585,7 +585,7 @@
       if (len > 0) \
         { \
           OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
-          std::streamsize n_bytes = size * len; \
+          std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
           stream.read (reinterpret_cast<char *> (ptr), n_bytes); \
           if (swap) \
             swap_bytes< size > (ptr, len); \
@@ -608,7 +608,7 @@
           OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
           for (octave_idx_type i = 0; i < len; i++) \
             ptr[i] = static_cast <TYPE> (data[i]);         \
-          std::streamsize n_bytes = size * len; \
+          std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
           stream.write (reinterpret_cast<char *> (ptr), n_bytes); \
         } \
     } \
@@ -807,7 +807,7 @@
     case LS_FLOAT:
       {
         OCTAVE_LOCAL_BUFFER (float, ptr, len);
-        std::streamsize n_bytes = 4 * len;
+        std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
         is.read (reinterpret_cast<char *> (ptr), n_bytes);
         do_float_format_conversion (ptr, len, fmt);
         for (octave_idx_type i = 0; i < len; i++)
@@ -865,7 +865,7 @@
 
     case LS_FLOAT: // No conversion necessary.
       {
-        std::streamsize n_bytes = 4 * len;
+        std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
         is.read (reinterpret_cast<char *> (data), n_bytes);
         do_float_format_conversion (data, len, fmt);
       }
@@ -874,7 +874,7 @@
     case LS_DOUBLE:
       {
         OCTAVE_LOCAL_BUFFER (double, ptr, len);
-        std::streamsize n_bytes = 8 * len;
+        std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
         is.read (reinterpret_cast<char *> (ptr), n_bytes);
         do_double_format_conversion (ptr, len, fmt);
         for (octave_idx_type i = 0; i < len; i++)
@@ -972,7 +972,7 @@
       {
         char tmp_type = static_cast<char> (type);
         os.write (&tmp_type, 1);
-        std::streamsize n_bytes = 4 * len;
+        std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
         os.write (reinterpret_cast <const char *> (data), n_bytes);
       }
       break;