aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Core/PlainObjectBase.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h
index c70db9247..84ef2b4da 100644
--- a/Eigen/src/Core/PlainObjectBase.h
+++ b/Eigen/src/Core/PlainObjectBase.h
@@ -34,6 +34,24 @@
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 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)
{
#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
+ internal::check_rows_cols_for_overflow(rows, cols);
Index size = rows*cols;
bool size_changed = size != this->size();
m_storage.resize(size, rows, cols);
if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
#else
+ internal::check_rows_cols_for_overflow(rows, cols);
m_storage.resize(rows*cols, rows, cols);
#endif
}
@@ -273,6 +293,7 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
{
const OtherDerived& other = _other.derived();
+ internal::check_rows_cols_for_overflow(other.rows(), other.cols());
const Index othersize = other.rows()*other.cols();
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())
{
_check_template_params();
+ internal::check_rows_cols_for_overflow((other.derived().rows(), other.derived().cols());
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)
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
+ internal::check_rows_cols_for_overflow(rows, cols);
m_storage.resize(rows*cols,rows,cols);
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
(!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);
}
else