Fix a bug in CompressedRowSparseMatrix::AppendRows The test for CompressedRowSparseMatrix::AppendRows tries to add a matrix of size zero, which results in an invalid pointer deferencing even though that pointer is never written to. Change-Id: I97dba37082bd5dad242ae1af0447a9178cd92027
diff --git a/docs/source/version_history.rst b/docs/source/version_history.rst index 664826c..87ad50e 100644 --- a/docs/source/version_history.rst +++ b/docs/source/version_history.rst
@@ -27,6 +27,9 @@ Bug Fixes & Minor Changes ------------------------- +#. Fix invalid memory access bug in + ``CompressedRowSparseMatrix::AppendRows`` when it was called with a + matrix of size zero. #. Build position independent code when compiling Ceres statically (Alexander Alekhin). #. Fix a bug in DetectStructure (Johannes Schonberger).
diff --git a/internal/ceres/compressed_row_sparse_matrix.cc b/internal/ceres/compressed_row_sparse_matrix.cc index 36f87a5..91d18bb 100644 --- a/internal/ceres/compressed_row_sparse_matrix.cc +++ b/internal/ceres/compressed_row_sparse_matrix.cc
@@ -241,16 +241,24 @@ << "The matrix being appended has: " << m.row_blocks().size() << " row blocks."; + if (m.num_rows() == 0) { + return; + } + if (cols_.size() < num_nonzeros() + m.num_nonzeros()) { cols_.resize(num_nonzeros() + m.num_nonzeros()); values_.resize(num_nonzeros() + m.num_nonzeros()); } // Copy the contents of m into this matrix. - std::copy(m.cols(), m.cols() + m.num_nonzeros(), &cols_[num_nonzeros()]); - std::copy(m.values(), - m.values() + m.num_nonzeros(), - &values_[num_nonzeros()]); + DCHECK_LT(num_nonzeros(), cols_.size()); + if (m.num_nonzeros() > 0) { + std::copy(m.cols(), m.cols() + m.num_nonzeros(), &cols_[num_nonzeros()]); + std::copy(m.values(), + m.values() + m.num_nonzeros(), + &values_[num_nonzeros()]); + } + rows_.resize(num_rows_ + m.num_rows() + 1); // new_rows = [rows_, m.row() + rows_[num_rows_]] std::fill(rows_.begin() + num_rows_,