]> gcc.gnu.org Git - gcc.git/commitdiff
vector.tcc (_M_insert_aux, [...]): Check at the outset that we are not trying to...
authorPaolo Carlini <pcarlini@suse.de>
Thu, 21 Oct 2004 14:53:02 +0000 (14:53 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 21 Oct 2004 14:53:02 +0000 (14:53 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/vector.tcc
libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/testsuite_allocator.h

index 8e5934e109e66630f8e5bd1b68346724d683cc89..f1d6e12395b620ea6707136b0efbdd0ab551839f 100644 (file)
@@ -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
index 4231715fb11b6bf55063b92e37a2928177a29691..5dc3cd41eb3ce0f081091a8598297734b4544c2f 100644 (file)
@@ -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 (file)
index 0000000..11c9e8d
--- /dev/null
@@ -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;
+}
index 7c353445e8a7baa70f31482ab4598aa9fab09d12..a13df804ed3549851629b0f1181f459a671dd234 100644 (file)
@@ -36,7 +36,6 @@
 #define _GLIBCXX_TESTSUITE_ALLOCATOR_H
 
 #include <cstddef>
-#include <cstdlib>
 #include <limits>
 
 namespace 
This page took 0.065656 seconds and 5 git commands to generate.