changeset 10359:ec05728ce7f0

guard against >2GB allocations with 32-bit ptrs on weird platforms
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 25 Feb 2010 14:45:32 +0100
parents 72fab01e5d68
children 9126d71f53aa
files liboctave/ChangeLog liboctave/oct-mem.h
diffstat 2 files changed, 19 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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  <highegg@gmail.com>
+
+	* oct-mem.h (safe_size_comp): New helper func.
+	(no_ctor_new): Call it here.
+
 2010-02-25  Jaroslav Hajek  <highegg@gmail.com>
 
 	* oct-mem.h (copy_or_memcpy, fill_or_memset, no_ctor_new): Accept
--- 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<size_t> (-1) / size)
+    throw std::bad_alloc ();
+  return n * size;
+}
+
 // Unaliased copy. This boils down to memcpy, even for octave_int and complex types.
 
 template <class T>
@@ -117,7 +124,12 @@
 // Memory allocated by octave_new should be freed by octave_delete.
 template <class T>
 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 <class T>
 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<T > (size_t n) \
-{ return reinterpret_cast<T *> (new char[n * sizeof (T)]); } \
+{ return reinterpret_cast<T *> (new char[safe_size_comp (n, sizeof (T))]); } \
 template <> \
 inline void no_ctor_delete<T > (T *ptr) \
 { delete [] reinterpret_cast<char *> (ptr); }