mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 03:39:01 +08:00
bug #363 - check for integer overflow in size=rows*cols computations
This commit is contained in:
parent
0c6055c285
commit
739559b08a
@ -34,6 +34,24 @@
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename Index>
|
||||||
|
void check_rows_cols_for_overflow(Index rows, Index cols)
|
||||||
|
{
|
||||||
|
#ifdef EIGEN_EXCEPTIONS
|
||||||
|
// http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
|
||||||
|
// we assume Index is signed
|
||||||
|
Index max_index = (Index(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
|
||||||
|
bool error = (x < 0 || y < 0) ? true
|
||||||
|
: (x == 0 || y == 0) ? false
|
||||||
|
: (x > max_index / y);
|
||||||
|
if (error)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
#else
|
||||||
|
(void) rows;
|
||||||
|
(void) cols;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
|
template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
|
||||||
|
|
||||||
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
|
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
|
||||||
@ -200,11 +218,13 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
|
EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
|
||||||
{
|
{
|
||||||
#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
|
#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
|
||||||
|
internal::check_rows_cols_for_overflow(rows, cols);
|
||||||
Index size = rows*cols;
|
Index size = rows*cols;
|
||||||
bool size_changed = size != this->size();
|
bool size_changed = size != this->size();
|
||||||
m_storage.resize(size, rows, cols);
|
m_storage.resize(size, rows, cols);
|
||||||
if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
||||||
#else
|
#else
|
||||||
|
internal::check_rows_cols_for_overflow(rows, cols);
|
||||||
m_storage.resize(rows*cols, rows, cols);
|
m_storage.resize(rows*cols, rows, cols);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -273,6 +293,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
|
EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
|
||||||
{
|
{
|
||||||
const OtherDerived& other = _other.derived();
|
const OtherDerived& other = _other.derived();
|
||||||
|
internal::check_rows_cols_for_overflow(other.rows(), other.cols());
|
||||||
const Index othersize = other.rows()*other.cols();
|
const Index othersize = other.rows()*other.cols();
|
||||||
if(RowsAtCompileTime == 1)
|
if(RowsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
@ -417,6 +438,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
: m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
|
: m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
|
||||||
{
|
{
|
||||||
_check_template_params();
|
_check_template_params();
|
||||||
|
internal::check_rows_cols_for_overflow((other.derived().rows(), other.derived().cols());
|
||||||
Base::operator=(other.derived());
|
Base::operator=(other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,6 +603,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
{
|
{
|
||||||
eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
||||||
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
|
||||||
|
internal::check_rows_cols_for_overflow(rows, cols);
|
||||||
m_storage.resize(rows*cols,rows,cols);
|
m_storage.resize(rows*cols,rows,cols);
|
||||||
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
|
||||||
}
|
}
|
||||||
@ -638,6 +661,7 @@ struct internal::conservative_resize_like_impl
|
|||||||
if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
|
if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
|
||||||
(!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
|
(!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
|
||||||
{
|
{
|
||||||
|
internal::check_rows_cols_for_overflow(rows, cols);
|
||||||
_this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
|
_this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user