aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen
diff options
context:
space:
mode:
authorGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2011-10-16 16:12:19 -0400
committerGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2011-10-16 16:12:19 -0400
commit0c6055c285e341b6a447558cf61e36ed5ba814cb (patch)
tree21a65b901951302c79dc720de494225b1313343f /Eigen
parentc1170d2e9305620e01c22bad30cc1e65ae695f0d (diff)
bug #363 - check for integer overflow in byte-size computations
Diffstat (limited to 'Eigen')
-rw-r--r--Eigen/src/Core/util/Memory.h21
1 files changed, 21 insertions, 0 deletions
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index cd5299a0e..5afe8dae5 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -347,18 +347,31 @@ template<typename T> inline void destruct_elements_of_array(T *ptr, size_t size)
*** Implementation of aligned new/delete-like functions ***
*****************************************************************************/
+template<typename T>
+inline void check_size_for_overflow(size_t size)
+{
+ #ifdef EIGEN_EXCEPTIONS
+ if(size > size_t(-1) / sizeof(T))
+ throw std::bad_alloc();
+ #else
+ (void) size;
+ #endif
+}
+
/** \internal Allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment.
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
* The default constructor of T is called.
*/
template<typename T> inline T* aligned_new(size_t size)
{
+ check_size_for_overflow<T>(size);
T *result = reinterpret_cast<T*>(aligned_malloc(sizeof(T)*size));
return construct_elements_of_array(result, size);
}
template<typename T, bool Align> inline T* conditional_aligned_new(size_t size)
{
+ check_size_for_overflow<T>(size);
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
return construct_elements_of_array(result, size);
}
@@ -383,6 +396,8 @@ template<typename T, bool Align> inline void conditional_aligned_delete(T *ptr,
template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pts, size_t new_size, size_t old_size)
{
+ check_size_for_overflow<T>(new_size);
+ check_size_for_overflow<T>(old_size);
if(new_size < old_size)
destruct_elements_of_array(pts+new_size, old_size-new_size);
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
@@ -394,6 +409,7 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pt
template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t size)
{
+ check_size_for_overflow<T>(size);
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
if(NumTraits<T>::RequireInitialization)
construct_elements_of_array(result, size);
@@ -402,6 +418,8 @@ template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t s
template<typename T, bool Align> inline T* conditional_aligned_realloc_new_auto(T* pts, size_t new_size, size_t old_size)
{
+ check_size_for_overflow<T>(new_size);
+ check_size_for_overflow<T>(old_size);
if(NumTraits<T>::RequireInitialization && (new_size < old_size))
destruct_elements_of_array(pts+new_size, old_size-new_size);
T *result = reinterpret_cast<T*>(conditional_aligned_realloc<Align>(reinterpret_cast<void*>(pts), sizeof(T)*new_size, sizeof(T)*old_size));
@@ -557,6 +575,7 @@ template<typename T> class aligned_stack_memory_handler
#endif
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
+ Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
TYPE* NAME = (BUFFER)!=0 ? (BUFFER) \
: reinterpret_cast<TYPE*>( \
(sizeof(TYPE)*SIZE<=EIGEN_STACK_ALLOCATION_LIMIT) ? EIGEN_ALIGNED_ALLOCA(sizeof(TYPE)*SIZE) \
@@ -566,6 +585,7 @@ template<typename T> class aligned_stack_memory_handler
#else
#define ei_declare_aligned_stack_constructed_variable(TYPE,NAME,SIZE,BUFFER) \
+ Eigen::internal::check_size_for_overflow<TYPE>(SIZE); \
TYPE* NAME = (BUFFER)!=0 ? BUFFER : reinterpret_cast<TYPE*>(Eigen::internal::aligned_malloc(sizeof(TYPE)*SIZE)); \
Eigen::internal::aligned_stack_memory_handler<TYPE> EIGEN_CAT(NAME,_stack_memory_destructor)((BUFFER)==0 ? NAME : 0,SIZE,true)
@@ -690,6 +710,7 @@ public:
pointer allocate( size_type num, const void* hint = 0 )
{
EIGEN_UNUSED_VARIABLE(hint);
+ internal::check_size_for_overflow<T>(num);
return static_cast<pointer>( internal::aligned_malloc( num * sizeof(T) ) );
}