diff options
author | Paolo Carlini <pcarlini@suse.de> | 2004-10-21 14:53:02 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2004-10-21 14:53:02 +0000 |
commit | 996e539545fa047c2df21645768d40cb67f50acf (patch) | |
tree | 29f654e743ccdc49ae3d5ac87f9a553d8351ef6e | |
parent | d600a3a435e1a8556480916886e895cbc5ead8dd (diff) | |
download | gcc-996e539545fa047c2df21645768d40cb67f50acf.tar.gz |
vector.tcc (_M_insert_aux, [...]): Check at the outset that we are not trying to exceed max_size...
2004-10-21 Paolo Carlini <pcarlini@suse.de>
Dhruv Matani <dhruvbird@gmx.net>
Nathan Myers <ncm@cantrip.org>
* include/bits/vector.tcc (_M_insert_aux, _M_fill_insert,
_M_range_insert): Check at the outset that we are not trying
to exceed max_size, then deal properly with __len overflows.
* testsuite/23_containers/vector/modifiers/insert/1.cc: New.
* testsuite/testsuite_allocator.h: Remove redundant include.
Co-Authored-By: Dhruv Matani <dhruvbird@gmx.net>
Co-Authored-By: Nathan Myers <ncm@cantrip.org>
From-SVN: r89377
-rw-r--r-- | libstdc++-v3/ChangeLog | 11 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/vector.tcc | 33 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/1.cc | 58 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/testsuite_allocator.h | 1 |
4 files changed, 97 insertions, 6 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8e5934e109e..f1d6e12395b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2004-10-21 Paolo Carlini <pcarlini@suse.de> + Dhruv Matani <dhruvbird@gmx.net> + Nathan Myers <ncm@cantrip.org> + + * include/bits/vector.tcc (_M_insert_aux, _M_fill_insert, + _M_range_insert): Check at the outset that we are not trying + to exceed max_size, then deal properly with __len overflows. + * testsuite/23_containers/vector/modifiers/insert/1.cc: New. + + * testsuite/testsuite_allocator.h: Remove redundant include. + 2004-10-20 Paolo Carlini <pcarlini@suse.de> * include/ext/bitmap_allocator.h (allocate): Throw std::bad_alloc diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc index 4231715fb11..5dc3cd41eb3 100644 --- a/libstdc++-v3/include/bits/vector.tcc +++ b/libstdc++-v3/include/bits/vector.tcc @@ -262,7 +262,16 @@ namespace _GLIBCXX_STD else { const size_type __old_size = size(); - const size_type __len = __old_size != 0 ? 2 * __old_size : 1; + if (__old_size == this->max_size()) + __throw_length_error(__N("vector::_M_insert_aux")); + + // When sizeof(value_type) == 1 and __old_size > size_type(-1)/2 + // __len overflows: if we don't notice and _M_allocate doesn't + // throw we crash badly later. + size_type __len = __old_size != 0 ? 2 * __old_size : 1; + if (__len < __old_size) + __len = this->max_size(); + iterator __new_start(this->_M_allocate(__len)); iterator __new_finish(__new_start); try @@ -279,7 +288,7 @@ namespace _GLIBCXX_STD iterator(this->_M_impl._M_finish), __new_finish, this->get_allocator()); - } + } catch(...) { std::_Destroy(__new_start, __new_finish, this->get_allocator()); @@ -337,7 +346,14 @@ namespace _GLIBCXX_STD else { const size_type __old_size = size(); - const size_type __len = __old_size + std::max(__old_size, __n); + if (this->max_size() - __old_size < __n) + __throw_length_error(__N("vector::_M_fill_insert")); + + // See _M_insert_aux above. + size_type __len = __old_size + std::max(__old_size, __n); + if (__len < __old_size) + __len = this->max_size(); + iterator __new_start(this->_M_allocate(__len)); iterator __new_finish(__new_start); try @@ -389,7 +405,7 @@ namespace _GLIBCXX_STD template<typename _ForwardIterator> void vector<_Tp, _Alloc>:: - _M_range_insert(iterator __position,_ForwardIterator __first, + _M_range_insert(iterator __position, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { if (__first != __last) @@ -429,7 +445,14 @@ namespace _GLIBCXX_STD else { const size_type __old_size = size(); - const size_type __len = __old_size + std::max(__old_size, __n); + if (this->max_size() - __old_size < __n) + __throw_length_error(__N("vector::_M_range_insert")); + + // See _M_insert_aux above. + size_type __len = __old_size + std::max(__old_size, __n); + if (__len < __old_size) + __len = this->max_size(); + iterator __new_start(this->_M_allocate(__len)); iterator __new_finish(__new_start); try diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/1.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/1.cc new file mode 100644 index 00000000000..11c9e8dee33 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/1.cc @@ -0,0 +1,58 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include <vector> +#include <stdexcept> +#include <testsuite_hooks.h> + +void +test01() +{ + bool test __attribute__((unused)) = true; + using namespace std; + + vector<int> iv; + + try + { + iv.insert(iv.end(), iv.max_size() + 1, 1); + } + catch(std::length_error&) + { + VERIFY( true ); + } + catch(...) + { + VERIFY( false ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/testsuite_allocator.h b/libstdc++-v3/testsuite/testsuite_allocator.h index 7c353445e8a..a13df804ed3 100644 --- a/libstdc++-v3/testsuite/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/testsuite_allocator.h @@ -36,7 +36,6 @@ #define _GLIBCXX_TESTSUITE_ALLOCATOR_H #include <cstddef> -#include <cstdlib> #include <limits> namespace |