diff options
author | Krzesimir Nowak <qdlacz@gmail.com> | 2011-03-20 19:39:39 +0100 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2011-03-21 09:23:08 +0100 |
commit | defb0eba23019ab01dbf7a80bfa6b2d87a4bc2a4 (patch) | |
tree | 709b35355d52df33f50ff5b7132720b3e8ec5d63 | |
parent | 29198769ae1927629186a53642a7de3e13c36c68 (diff) | |
download | glibmm-defb0eba23019ab01dbf7a80bfa6b2d87a4bc2a4.tar.gz |
Vectorutils, ArrayHandle: Check for NULL pointers.
* glib/glibmm/vectorutils.[h|cc]: Don't crash in compute_array_size2, when
NULL is passed - in that case just return 0. Also, array_to_vector method
return empty vector in such case.
* glib/glibmm/arrayhandle.[h|cc]: Set array_size to zero if passed array
is NULL.
* tests/glibmm_null_vectorutils/main.cc: New test for NULL arrays and lists
for vectorutils.
* tests/glibmm_null_containerhandle/main.cc: New test for NULL arrays and lists
for containerhandles.
* tests/Makefile.am: Added new tests to build.
Spotted by Kalev Lember. Bug #645245.
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | glib/glibmm/arrayhandle.cc | 2 | ||||
-rw-r--r-- | glib/glibmm/arrayhandle.h | 12 | ||||
-rw-r--r-- | glib/glibmm/vectorutils.cc | 21 | ||||
-rw-r--r-- | glib/glibmm/vectorutils.h | 32 | ||||
-rw-r--r-- | tests/Makefile.am | 38 | ||||
-rw-r--r-- | tests/glibmm_null_containerhandle/main.cc | 43 | ||||
-rw-r--r-- | tests/glibmm_null_vectorutils/main.cc | 41 | ||||
-rw-r--r-- | tests/glibmm_vector/main.cc | 4 |
9 files changed, 162 insertions, 46 deletions
@@ -1,3 +1,18 @@ +2011-03-20 Krzesimir Nowak <qdlacz@gmail.com> + + Vectorutils, ArrayHandle: Check for NULL pointers. + + * glib/glibmm/vectorutils.[h|cc]: Don't crash in compute_array_size2, when + NULL is passed - in that case just return 0. Also, array_to_vector method + return empty vector in such case. + * glib/glibmm/arrayhandle.[h|cc]: Set array_size to zero if passed array + is NULL. + * tests/glibmm_null_vectorutils/main.cc: New test for NULL arrays and lists + for vectorutils. + * tests/glibmm_null_containerhandle/main.cc: New test for NULL arrays and lists + for containerhandles. + * tests/Makefile.am: Added new tests to build. + 2011-03-21 Murray Cumming <murrayc@murrayc.com> Date: Document that some methods return *this, and why. diff --git a/glib/glibmm/arrayhandle.cc b/glib/glibmm/arrayhandle.cc index cc8e25a5..ce153c73 100644 --- a/glib/glibmm/arrayhandle.cc +++ b/glib/glibmm/arrayhandle.cc @@ -22,7 +22,7 @@ namespace Glib ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::~ArrayHandle() { - if(ownership_ != Glib::OWNERSHIP_NONE) + if(parray_ && ownership_ != Glib::OWNERSHIP_NONE) { if(ownership_ != Glib::OWNERSHIP_SHALLOW) { diff --git a/glib/glibmm/arrayhandle.h b/glib/glibmm/arrayhandle.h index 5f9702a6..e7d3e539 100644 --- a/glib/glibmm/arrayhandle.h +++ b/glib/glibmm/arrayhandle.h @@ -208,10 +208,10 @@ private: /** This is an intermediate type. When a method takes this, or returns this, you - * should use a standard C++ container of your choice, such as std::list or + * should use a standard C++ container of your choice, such as std::list or * std::vector. * - * However, this is not used in new API. We now prefer to just use std::vector, + * However, this is not used in new API. We now prefer to just use std::vector, * which is less flexibile, but makes the API clearer. * * @ingroup ContHandles @@ -328,7 +328,7 @@ private: * container such as std::list<Glib::ustring> or std::vector<Glib::ustring>. * * - * However, this is not used in new API. We now prefer to just use std::vector, + * However, this is not used in new API. We now prefer to just use std::vector, * which is less flexibile, but makes the API clearer. * * @ingroup ContHandles @@ -471,7 +471,7 @@ template <class T, class Tr> inline ArrayHandle<T,Tr>::ArrayHandle(const typename ArrayHandle<T,Tr>::CType* array, size_t array_size, Glib::OwnershipType ownership) : - size_ (array_size), + size_ ((array) ? array_size : 0), parray_ (array), ownership_ (ownership) {} @@ -498,7 +498,7 @@ ArrayHandle<T,Tr>::ArrayHandle(const ArrayHandle<T,Tr>& other) template <class T, class Tr> ArrayHandle<T,Tr>::~ArrayHandle() { - if(ownership_ != Glib::OWNERSHIP_NONE) + if(parray_ && ownership_ != Glib::OWNERSHIP_NONE) { if(ownership_ != Glib::OWNERSHIP_SHALLOW) { @@ -622,7 +622,7 @@ inline ArrayHandle<bool,Container_Helpers::TypeTraits<bool> >::ArrayHandle(const gboolean* array, size_t array_size, Glib::OwnershipType ownership) : - size_ (array_size), + size_ ((array) ? array_size : 0), parray_ (array), ownership_ (ownership) {} diff --git a/glib/glibmm/vectorutils.cc b/glib/glibmm/vectorutils.cc index caf3891a..b7cf34c2 100644 --- a/glib/glibmm/vectorutils.cc +++ b/glib/glibmm/vectorutils.cc @@ -23,8 +23,7 @@ namespace Glib namespace Container_Helpers { -gboolean* create_bool_array(std::vector<bool>::const_iterator pbegin, - size_t size) +gboolean* create_bool_array(std::vector<bool>::const_iterator pbegin, size_t size) { gboolean *const array(static_cast<gboolean*>(g_malloc((size + 1) * sizeof(gboolean)))); gboolean *const array_end(array + size); @@ -46,16 +45,20 @@ gboolean* create_bool_array(std::vector<bool>::const_iterator pbegin, ArrayHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::VectorType ArrayHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::array_to_vector(const CType* array, size_t array_size, Glib::OwnershipType ownership) { - // it will handle destroying data depending on passed ownership. - ArrayKeeperType keeper(array, array_size, ownership); + if(array) + { + // it will handle destroying data depending on passed ownership. + ArrayKeeperType keeper(array, array_size, ownership); #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS - return VectorType(ArrayIteratorType(array), ArrayIteratorType(array + array_size)); + return VectorType(ArrayIteratorType(array), ArrayIteratorType(array + array_size)); #else - VectorType temp; - temp.reserve(array_size); - Glib::Container_Helpers::fill_container(temp, ArrayIteratorType(array), ArrayIteratorType(array + array_size)); - return temp; + VectorType temp; + temp.reserve(array_size); + Glib::Container_Helpers::fill_container(temp, ArrayIteratorType(array), ArrayIteratorType(array + array_size)); + return temp; #endif + } + return VectorType(); } ArrayHandler<bool, Glib::Container_Helpers::TypeTraits<bool> >::VectorType diff --git a/glib/glibmm/vectorutils.h b/glib/glibmm/vectorutils.h index 87a91511..6796d838 100644 --- a/glib/glibmm/vectorutils.h +++ b/glib/glibmm/vectorutils.h @@ -70,14 +70,18 @@ namespace Container_Helpers template <class T> inline size_t compute_array_size2(const T* array) { - const T* pend(array); - - while(*pend) + if(array) { - ++pend; + const T* pend(array); + + while(*pend) + { + ++pend; + } + return(pend - array); } - return(pend - array); + return 0; } /* Allocate and fill a 0-terminated array. The size argument @@ -899,16 +903,20 @@ template <typename T, class Tr> typename ArrayHandler<T, Tr>::VectorType ArrayHandler<T, Tr>::array_to_vector(const CType* array, size_t array_size, Glib::OwnershipType ownership) { - // it will handle destroying data depending on passed ownership. - ArrayKeeperType keeper(array, array_size, ownership); + if (array) + { + // it will handle destroying data depending on passed ownership. + ArrayKeeperType keeper(array, array_size, ownership); #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS - return VectorType(ArrayIteratorType(array), ArrayIteratorType(array + array_size)); + return VectorType(ArrayIteratorType(array), ArrayIteratorType(array + array_size)); #else - VectorType temp; - temp.reserve(array_size); - Glib::Container_Helpers::fill_container(temp, ArrayIteratorType(array), ArrayIteratorType(array + array_size)); - return temp; + VectorType temp; + temp.reserve(array_size); + Glib::Container_Helpers::fill_container(temp, ArrayIteratorType(array), ArrayIteratorType(array + array_size)); + return temp; #endif + } + return VectorType(); } template <typename T, class Tr> diff --git a/tests/Makefile.am b/tests/Makefile.am index a1f2aa28..dc8bcb45 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -## Copyright (c) 2009, 2010 Openismus GmbH <http://www.openismus.com/> +## Copyright (c) 2009, 2010, 2011 Openismus GmbH <http://www.openismus.com/> ## ## This file is part of glibmm. ## @@ -19,7 +19,7 @@ AUTOMAKE_OPTIONS = subdir-objects check_PROGRAMS = \ giomm_ioerror/test \ - giomm_ioerror_and_iodbuserror/test \ + giomm_ioerror_and_iodbuserror/test \ giomm_simple/test \ giomm_asyncresult_sourceobject/test \ glibmm_btree/test \ @@ -33,7 +33,9 @@ check_PROGRAMS = \ glibmm_variant/test \ glibmm_vector/test \ glibmm_bool_vector/test \ - glibmm_bool_arrayhandle/test + glibmm_bool_arrayhandle/test \ + glibmm_null_vectorutils/test \ + glibmm_null_containerhandle/test TESTS = $(check_PROGRAMS) @@ -62,16 +64,20 @@ giomm_simple_test_LDADD = $(giomm_ldadd) giomm_asyncresult_sourceobject_test_SOURCES = giomm_asyncresult_sourceobject/main.cc giomm_asyncresult_sourceobject_test_LDADD = $(giomm_ldadd) -glibmm_btree_test_SOURCES = glibmm_btree/main.cc -glibmm_buildfilename_test_SOURCES = glibmm_buildfilename/main.cc -glibmm_date_test_SOURCES = glibmm_date/main.cc -glibmm_nodetree_test_SOURCES = glibmm_nodetree/main.cc -glibmm_ustring_compose_test_SOURCES = glibmm_ustring_compose/main.cc -glibmm_ustring_format_test_SOURCES = glibmm_ustring_format/main.cc -glibmm_value_test_SOURCES = glibmm_value/glibmm_value.cc glibmm_value/main.cc -glibmm_valuearray_test_SOURCES = glibmm_valuearray/main.cc -glibmm_variant_test_SOURCES = glibmm_variant/main.cc -glibmm_vector_test_SOURCES = glibmm_vector/main.cc -glibmm_vector_test_LDADD = $(giomm_ldadd) -glibmm_bool_vector_test_SOURCES = glibmm_bool_vector/main.cc -glibmm_bool_arrayhandle_test_SOURCES = glibmm_bool_arrayhandle/main.cc +glibmm_btree_test_SOURCES = glibmm_btree/main.cc +glibmm_buildfilename_test_SOURCES = glibmm_buildfilename/main.cc +glibmm_date_test_SOURCES = glibmm_date/main.cc +glibmm_nodetree_test_SOURCES = glibmm_nodetree/main.cc +glibmm_ustring_compose_test_SOURCES = glibmm_ustring_compose/main.cc +glibmm_ustring_format_test_SOURCES = glibmm_ustring_format/main.cc +glibmm_value_test_SOURCES = glibmm_value/glibmm_value.cc glibmm_value/main.cc +glibmm_valuearray_test_SOURCES = glibmm_valuearray/main.cc +glibmm_variant_test_SOURCES = glibmm_variant/main.cc +glibmm_vector_test_SOURCES = glibmm_vector/main.cc +glibmm_vector_test_LDADD = $(giomm_ldadd) +glibmm_bool_vector_test_SOURCES = glibmm_bool_vector/main.cc +glibmm_bool_arrayhandle_test_SOURCES = glibmm_bool_arrayhandle/main.cc +glibmm_null_vectorutils_test_SOURCES = glibmm_null_vectorutils/main.cc +glibmm_null_vectorutils_test_LDADD = $(giomm_ldadd) +glibmm_null_containerhandle_test_SOURCES = glibmm_null_containerhandle/main.cc +glibmm_null_containerhandle_test_LDADD = $(giomm_ldadd) diff --git a/tests/glibmm_null_containerhandle/main.cc b/tests/glibmm_null_containerhandle/main.cc new file mode 100644 index 00000000..596457d0 --- /dev/null +++ b/tests/glibmm_null_containerhandle/main.cc @@ -0,0 +1,43 @@ +/* Copyright (C) 2011 The gtkmm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <glibmm/arrayhandle.h> +#include <glibmm/listhandle.h> +#include <glibmm/slisthandle.h> + +#include <giomm/credentials.h> +#include <giomm/init.h> + +int +main() +{ + Gio::init(); + typedef Glib::RefPtr<Gio::Credentials> CrePtr; + + std::vector<CrePtr> v1(Glib::ArrayHandle<CrePtr>(0, Glib::OWNERSHIP_DEEP)); + std::vector<CrePtr> v2(Glib::ArrayHandle<CrePtr>(0, 5, Glib::OWNERSHIP_DEEP)); + std::vector<CrePtr> v3(Glib::ListHandle<CrePtr>(0, Glib::OWNERSHIP_DEEP)); + std::vector<CrePtr> v4(Glib::SListHandle<CrePtr>(0, Glib::OWNERSHIP_DEEP)); + std::vector<bool> v5(Glib::ArrayHandle<bool>(0, Glib::OWNERSHIP_DEEP)); + std::vector<bool> v6(Glib::ArrayHandle<bool>(0, 5, Glib::OWNERSHIP_DEEP)); + + if (v1.empty() && v2.empty() && v3.empty() && v4.empty() && v5.empty() && v6.empty()) + { + return 0; + } + return 1; +} diff --git a/tests/glibmm_null_vectorutils/main.cc b/tests/glibmm_null_vectorutils/main.cc new file mode 100644 index 00000000..567d4177 --- /dev/null +++ b/tests/glibmm_null_vectorutils/main.cc @@ -0,0 +1,41 @@ +/* Copyright (C) 2011 The gtkmm Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <glibmm/vectorutils.h> + +#include <giomm/credentials.h> +#include <giomm/init.h> + +int +main() +{ + Gio::init(); + typedef Glib::RefPtr<Gio::Credentials> CrePtr; + + std::vector<CrePtr> v1(Glib::ArrayHandler<CrePtr>::array_to_vector(0, Glib::OWNERSHIP_DEEP)); + std::vector<CrePtr> v2(Glib::ArrayHandler<CrePtr>::array_to_vector(0, 5, Glib::OWNERSHIP_DEEP)); + std::vector<CrePtr> v3(Glib::ListHandler<CrePtr>::list_to_vector(0, Glib::OWNERSHIP_DEEP)); + std::vector<CrePtr> v4(Glib::SListHandler<CrePtr>::slist_to_vector(0, Glib::OWNERSHIP_DEEP)); + std::vector<bool> v5(Glib::ArrayHandler<bool>::array_to_vector(0, Glib::OWNERSHIP_DEEP)); + std::vector<bool> v6(Glib::ArrayHandler<bool>::array_to_vector(0, 5, Glib::OWNERSHIP_DEEP)); + + if (v1.empty() && v2.empty() && v3.empty() && v4.empty() && v5.empty() && v6.empty()) + { + return 0; + } + return 1; +} diff --git a/tests/glibmm_vector/main.cc b/tests/glibmm_vector/main.cc index db6d2f61..b1ae14bb 100644 --- a/tests/glibmm_vector/main.cc +++ b/tests/glibmm_vector/main.cc @@ -46,7 +46,7 @@ create_list() { head = g_list_prepend(head, g_credentials_new()); } - + return g_list_reverse(head); } @@ -78,7 +78,7 @@ create_slist() { head = g_slist_prepend(head, g_credentials_new()); } - + return g_slist_reverse(head); } |