diff options
Diffstat (limited to 'libstdc++-v3/libsupc++/vec.cc')
-rw-r--r-- | libstdc++-v3/libsupc++/vec.cc | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/libstdc++-v3/libsupc++/vec.cc b/libstdc++-v3/libsupc++/vec.cc index 700c5ef431d..f9afd39df9b 100644 --- a/libstdc++-v3/libsupc++/vec.cc +++ b/libstdc++-v3/libsupc++/vec.cc @@ -1,7 +1,6 @@ // New abi Support -*- C++ -*- -// Copyright (C) 2000, 2001, 2003, 2004, 2009, 2011 -// Free Software Foundation, Inc. +// Copyright (C) 2000-2012 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -59,6 +58,19 @@ namespace __cxxabiv1 globals->caughtExceptions = p->nextException; globals->uncaughtExceptions += 1; } + + // Compute the total size with overflow checking. + std::size_t compute_size(std::size_t element_count, + std::size_t element_size, + std::size_t padding_size) + { + if (element_size && element_count > std::size_t(-1) / element_size) + throw std::bad_alloc(); + std::size_t size = element_count * element_size; + if (size + padding_size < size) + throw std::bad_alloc(); + return size + padding_size; + } } // Allocate and construct array. @@ -83,7 +95,8 @@ namespace __cxxabiv1 void *(*alloc) (std::size_t), void (*dealloc) (void *)) { - std::size_t size = element_count * element_size + padding_size; + std::size_t size + = compute_size(element_count, element_size, padding_size); char *base = static_cast <char *> (alloc (size)); if (!base) return base; @@ -124,7 +137,8 @@ namespace __cxxabiv1 void *(*alloc) (std::size_t), void (*dealloc) (void *, std::size_t)) { - std::size_t size = element_count * element_size + padding_size; + std::size_t size + = compute_size(element_count, element_size, padding_size); char *base = static_cast<char *>(alloc (size)); if (!base) return base; |