# HG changeset patch # User Rik # Date 1455470533 28800 # Node ID af8118df8292158073998ab2d532049c1c4d42e7 # Parent 076876f0a83a251565bf8981f45042839057f81d# Parent a93fa1b0796e347fed23a9b2e650a57ac02dc3c2 maint: merge stable to default. diff -r 076876f0a83a -r af8118df8292 liboctave/array/Sparse.cc --- a/liboctave/array/Sparse.cc Fri Feb 12 18:07:07 2016 -0800 +++ b/liboctave/array/Sparse.cc Sun Feb 14 09:22:13 2016 -0800 @@ -815,22 +815,35 @@ octave_idx_type kk = 0; retval.xcidx (0) = 0; + // quotient and remainder of i * old_nr divided by new_nr + // Track them individually to avoid overflow (bug #42850). + octave_idx_type i_old_qu = 0; + octave_idx_type i_old_rm = static_cast (-old_nr); for (octave_idx_type i = 0; i < old_nc; i++) - for (octave_idx_type j = cidx (i); j < cidx (i+1); j++) - { - octave_idx_type tmp = i * old_nr + ridx (j); - if (tmp < 0) - (*current_liboctave_error_handler) - ("reshape: overflow in octave_idx_type prevents reshaping array"); - - octave_idx_type ii = tmp % new_nr; - octave_idx_type jj = (tmp - ii) / new_nr; - for (octave_idx_type k = kk; k < jj; k++) - retval.xcidx (k+1) = j; - kk = jj; - retval.xdata (j) = data (j); - retval.xridx (j) = ii; - } + { + i_old_rm += old_nr; + if (i_old_rm >= new_nr) + { + i_old_qu += i_old_rm / new_nr; + i_old_rm = i_old_rm % new_nr; + } + for (octave_idx_type j = cidx (i); j < cidx (i+1); j++) + { + octave_idx_type ii, jj; + ii = (i_old_rm + ridx (j)) % new_nr; + jj = i_old_qu + (i_old_rm + ridx (j)) / new_nr; + + // Original calculation subject to overflow + // ii = (i*old_nr + ridx (j)) % new_nr + // jj = (i*old_nr + ridx (j)) / new_nr + + for (octave_idx_type k = kk; k < jj; k++) + retval.xcidx (k+1) = j; + kk = jj; + retval.xdata (j) = data (j); + retval.xridx (j) = ii; + } + } for (octave_idx_type k = kk; k < new_nc; k++) retval.xcidx (k+1) = new_nnz; } @@ -2024,10 +2037,10 @@ if (new_nz > nz) { // Make room first. - std::copy (data () + ui, data () + nz, - data () + li + rnz); - std::copy (ridx () + ui, ridx () + nz, - ridx () + li + rnz); + std::copy_backward (data () + ui, data () + nz, + data () + new_nz); + std::copy_backward (ridx () + ui, ridx () + nz, + ridx () + new_nz); mx_inline_add2 (nc - ub, cidx () + ub + 1, new_nz - nz); }