# HG changeset patch # User Rik # Date 1398645483 25200 # Node ID 9a6646cc7c3e7f99f04470b9aff1f482ff6c9edb # Parent 44f0d1a53eada384767b16005cba7ed13c5ea20b 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. diff -r 44f0d1a53ead -r 9a6646cc7c3e libinterp/corefcn/ls-mat4.cc --- 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 (*s++ & 0x00FF); } - os.write (reinterpret_cast (buf), nrow*ncol*sizeof (double)); + std::streamsize n_bytes = static_cast (nrow) * + static_cast (ncol) * + sizeof (double); + os.write (reinterpret_cast (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 (dtmp), 8 * len); + std::streamsize n_bytes = 8 * static_cast (len); + os.write (reinterpret_cast (dtmp), n_bytes); ds = nr; os.write (reinterpret_cast (&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 (dtmp), 8 * len); + os.write (reinterpret_cast (dtmp), n_bytes); ds = nc; os.write (reinterpret_cast (&ds), 8); for (octave_idx_type i = 0; i < len; i++) dtmp[i] = std::real (m.data (i)); - os.write (reinterpret_cast (dtmp), 8 * len); + os.write (reinterpret_cast (dtmp), n_bytes); ds = 0.; os.write (reinterpret_cast (&ds), 8); for (octave_idx_type i = 0; i < len; i++) dtmp[i] = std::imag (m.data (i)); - os.write (reinterpret_cast (dtmp), 8 * len); + os.write (reinterpret_cast (dtmp), n_bytes); os.write (reinterpret_cast (&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 (dtmp), 8 * len); + std::streamsize n_bytes = 8 * static_cast (len); + os.write (reinterpret_cast (dtmp), n_bytes); ds = nr; os.write (reinterpret_cast (&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 (dtmp), 8 * len); + os.write (reinterpret_cast (dtmp), n_bytes); ds = nc; os.write (reinterpret_cast (&ds), 8); - os.write (reinterpret_cast (m.data ()), 8 * len); + os.write (reinterpret_cast (m.data ()), n_bytes); ds = 0.; os.write (reinterpret_cast (&ds), 8); } @@ -567,7 +571,8 @@ else if (tc.is_real_matrix ()) { Matrix m = tc.matrix_value (); - os.write (reinterpret_cast (m.data ()), 8 * len); + std::streamsize n_bytes = 8 * static_cast (len); + os.write (reinterpret_cast (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 (m.data ()), 8 * len); + std::streamsize n_bytes = 8 * static_cast (len); + os.write (reinterpret_cast (m.data ()), n_bytes); m = ::imag (m_cmplx); - os.write (reinterpret_cast (m.data ()), 8 * len); + os.write (reinterpret_cast (m.data ()), n_bytes); } else gripe_wrong_type_arg ("save", tc, false); diff -r 44f0d1a53ead -r 9a6646cc7c3e libinterp/corefcn/ls-mat5.cc --- 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 (ptr), size * len); \ + std::streamsize n_bytes = size * static_cast (len); \ + stream.read (reinterpret_cast (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 (data[i]); \ - stream.write (reinterpret_cast (ptr), count * sizeof (TYPE)); \ + std::streamsize n_bytes = sizeof (TYPE) * static_cast (count); \ + stream.write (reinterpret_cast (ptr), n_bytes); \ } \ while (0) diff -r 44f0d1a53ead -r 9a6646cc7c3e liboctave/util/data-conv.cc --- 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 (len); \ stream.read (reinterpret_cast (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 (data[i]); \ - std::streamsize n_bytes = size * len; \ + std::streamsize n_bytes = size * static_cast (len); \ stream.write (reinterpret_cast (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 (len); is.read (reinterpret_cast (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 (len); is.read (reinterpret_cast (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 (len); is.read (reinterpret_cast (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 (type); os.write (&tmp_type, 1); - std::streamsize n_bytes = 4 * len; + std::streamsize n_bytes = 4 * static_cast (len); os.write (reinterpret_cast (data), n_bytes); } break;