[glibmm] Vectorutils, ArrayHandle: Check for NULL pointers.



commit defb0eba23019ab01dbf7a80bfa6b2d87a4bc2a4
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Sun Mar 20 19:39:39 2011 +0100

    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.

 ChangeLog                                 |   15 ++++++++++
 glib/glibmm/arrayhandle.cc                |    2 +-
 glib/glibmm/arrayhandle.h                 |   12 ++++----
 glib/glibmm/vectorutils.cc                |   21 ++++++++------
 glib/glibmm/vectorutils.h                 |   32 +++++++++++++--------
 tests/Makefile.am                         |   38 +++++++++++++++-----------
 tests/glibmm_null_containerhandle/main.cc |   43 +++++++++++++++++++++++++++++
 tests/glibmm_null_vectorutils/main.cc     |   41 +++++++++++++++++++++++++++
 tests/glibmm_vector/main.cc               |    4 +-
 9 files changed, 162 insertions(+), 46 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 986966c..9a01274 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 cc8e25a..ce153c7 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 5f9702a..e7d3e53 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 caf3891..b7cf34c 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 87a9151..6796d83 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 a1f2aa2..dc8bcb4 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 0000000..596457d
--- /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 0000000..567d417
--- /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 db6d2f6..b1ae14b 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);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]