aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2004-10-21 14:53:02 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2004-10-21 14:53:02 +0000
commit996e539545fa047c2df21645768d40cb67f50acf (patch)
tree29f654e743ccdc49ae3d5ac87f9a553d8351ef6e
parentd600a3a435e1a8556480916886e895cbc5ead8dd (diff)
downloadgcc-996e539545fa047c2df21645768d40cb67f50acf.zip
gcc-996e539545fa047c2df21645768d40cb67f50acf.tar.gz
gcc-996e539545fa047c2df21645768d40cb67f50acf.tar.bz2
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/ChangeLog11
-rw-r--r--libstdc++-v3/include/bits/vector.tcc33
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/1.cc58
-rw-r--r--libstdc++-v3/testsuite/testsuite_allocator.h1
4 files changed, 97 insertions, 6 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 8e5934e..f1d6e12 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 4231715..5dc3cd4 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 0000000..11c9e8d
--- /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 7c35344..a13df80 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