# HG changeset patch # User Jaroslav Hajek # Date 1267105532 -3600 # Node ID ec05728ce7f087a9e2f9f323f0814b25873714f1 # Parent 72fab01e5d68390bfb37f30aa630f479964fa8fb guard against >2GB allocations with 32-bit ptrs on weird platforms diff -r 72fab01e5d68 -r ec05728ce7f0 liboctave/ChangeLog --- a/liboctave/ChangeLog Thu Feb 25 12:55:13 2010 +0100 +++ b/liboctave/ChangeLog Thu Feb 25 14:45:32 2010 +0100 @@ -1,4 +1,8 @@ - +2010-02-25 Jaroslav Hajek + + * oct-mem.h (safe_size_comp): New helper func. + (no_ctor_new): Call it here. + 2010-02-25 Jaroslav Hajek * oct-mem.h (copy_or_memcpy, fill_or_memset, no_ctor_new): Accept diff -r 72fab01e5d68 -r ec05728ce7f0 liboctave/oct-mem.h --- a/liboctave/oct-mem.h Thu Feb 25 12:55:13 2010 +0100 +++ b/liboctave/oct-mem.h Thu Feb 25 14:45:32 2010 +0100 @@ -36,6 +36,13 @@ // but not theoretically guaranteed by the C++ standard. In the future, C++ may // provide a better way to accomplish these tasks. +inline size_t safe_size_comp (size_t n, size_t size) +{ + if (n > static_cast (-1) / size) + throw std::bad_alloc (); + return n * size; +} + // Unaliased copy. This boils down to memcpy, even for octave_int and complex types. template @@ -117,7 +124,12 @@ // Memory allocated by octave_new should be freed by octave_delete. template inline T *no_ctor_new (size_t n) -{ return new T[n]; } +{ + // Some systems let us allocate > 2GB memory even though size_t, which is either + // buggy or completely cuckoo, so let's check here to stay safe. + safe_size_comp (n, sizeof (T)); + return new T[n]; +} template inline void no_ctor_delete (T *ptr) { delete [] ptr; } @@ -125,7 +137,7 @@ #define DEFINE_POD_NEW_DELETE(T) \ template <> \ inline T *no_ctor_new (size_t n) \ -{ return reinterpret_cast (new char[n * sizeof (T)]); } \ +{ return reinterpret_cast (new char[safe_size_comp (n, sizeof (T))]); } \ template <> \ inline void no_ctor_delete (T *ptr) \ { delete [] reinterpret_cast (ptr); }