[glib] Bug 608196 - Overflow-safe g_new family



commit 343cbf25c7104f782b9d0070cb623c7605dab646
Author: Behdad Esfahbod <behdad behdad org>
Date:   Tue Feb 2 23:48:42 2010 -0500

    Bug 608196 - Overflow-safe g_new family
    
    New public API:
    
    g_malloc_n
    g_malloc0_n
    g_realloc_n
    g_try_malloc_n
    g_try_malloc0_n
    g_try_realloc_n

 docs/reference/glib/glib-sections.txt |    6 ++
 docs/reference/glib/tmpl/memory.sgml  |   82 ++++++++++++++++++++++++-
 glib/glib.symbols                     |    6 ++
 glib/gmem.c                           |   95 ++++++++++++++++++++++++++++-
 glib/gmem.h                           |   92 +++++++++++++++++++++++-----
 glib/tests/Makefile.am                |    3 +
 glib/tests/mem-overflow.c             |  108 +++++++++++++++++++++++++++++++++
 glib/tests/printf.c                   |    2 +-
 glib/tests/rand.c                     |    2 +-
 9 files changed, 375 insertions(+), 21 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index c771dd9..015a649 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -853,6 +853,12 @@ g_realloc
 g_try_malloc
 g_try_malloc0
 g_try_realloc
+g_malloc_n
+g_malloc0_n
+g_realloc_n
+g_try_malloc_n
+g_try_malloc0_n
+g_try_realloc_n
 
 <SUBSECTION>
 g_free
diff --git a/docs/reference/glib/tmpl/memory.sgml b/docs/reference/glib/tmpl/memory.sgml
index 90df4f8..c113e48 100644
--- a/docs/reference/glib/tmpl/memory.sgml
+++ b/docs/reference/glib/tmpl/memory.sgml
@@ -39,6 +39,7 @@ g_mem_set_vtable().
 Allocates @n_structs elements of type @struct_type.
 The returned pointer is cast to a pointer to the given type.
 If @n_structs is 0 it returns %NULL.
+Care is taken to avoid overflow when calculating the size of the allocated block.
 </para>
 <para>
 Since the returned pointer is already casted to the right type,
@@ -56,6 +57,7 @@ so might hide memory allocation errors.
 Allocates @n_structs elements of type @struct_type, initialized to 0's.
 The returned pointer is cast to a pointer to the given type.
 If @n_structs is 0 it returns %NULL.
+Care is taken to avoid overflow when calculating the size of the allocated block.
 </para>
 <para>
 Since the returned pointer is already casted to the right type,
@@ -73,6 +75,7 @@ so might hide memory allocation errors.
 Reallocates the memory pointed to by @mem, so that it now has space for
 @n_structs elements of type @struct_type. It returns the new address of 
 the memory, which may have been moved.
+Care is taken to avoid overflow when calculating the size of the allocated block.
 </para>
 
 @struct_type: the type of the elements to allocate
@@ -86,7 +89,7 @@ the memory, which may have been moved.
 Attempts to allocate @n_structs elements of type @struct_type, and returns 
 %NULL on failure. Contrast with g_new(), which aborts the program on failure.
 The returned pointer is cast to a pointer to the given type. 
-If @n_structs is 0 it returns %NULL.
+The function returns %NULL when @n_structs is 0 of if an overflow occurs.
 </para>
 
 @struct_type: the type of the elements to allocate
@@ -101,7 +104,7 @@ Attempts to allocate @n_structs elements of type @struct_type, initialized
 to 0's, and returns %NULL on failure. Contrast with g_new0(), which aborts 
 the program on failure.
 The returned pointer is cast to a pointer to the given type.
-The function returns %NULL when @n_structs is 0.
+The function returns %NULL when @n_structs is 0 of if an overflow occurs.
 </para>
 
 @struct_type: the type of the elements to allocate
@@ -116,6 +119,7 @@ Attempts to reallocate the memory pointed to by @mem, so that it now has
 space for @n_structs elements of type @struct_type, and returns %NULL on 
 failure. Contrast with g_renew(), which aborts the program on failure.
 It returns the new address of the memory, which may have been moved.
+The function returns %NULL if an overflow occurs.
 </para>
 
 @struct_type: the type of the elements to allocate
@@ -192,6 +196,80 @@ on failure. If @mem is %NULL, behaves the same as g_try_malloc().
 @Returns: the allocated memory, or %NULL.
 
 
+<!-- ##### FUNCTION g_malloc_n ##### -->
+<para>
+This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
+but care is taken to detect possible overflow during multiplication.
+</para>
+
+ n_blocks: the number of blocks to allocate
+ n_block_bytes: the size of each block in bytes
+ Returns: a pointer to the allocated memory
+ Since: 2.24
+
+
+<!-- ##### FUNCTION g_malloc0_n ##### -->
+<para>
+This function is similar to g_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
+but care is taken to detect possible overflow during multiplication.
+</para>
+
+ n_blocks: the number of blocks to allocate
+ n_block_bytes: the size of each block in bytes
+ Returns: a pointer to the allocated memory
+ Since: 2.24
+
+
+<!-- ##### FUNCTION g_realloc_n ##### -->
+<para>
+This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
+but care is taken to detect possible overflow during multiplication.
+</para>
+
+ mem: the memory to reallocate
+ n_blocks: the number of blocks to allocate
+ n_block_bytes: the size of each block in bytes
+ Returns: the new address of the allocated memory
+ Since: 2.24
+
+
+<!-- ##### FUNCTION g_try_malloc_n ##### -->
+<para>
+This function is similar to g_try_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
+but care is taken to detect possible overflow during multiplication.
+</para>
+
+ n_blocks: the number of blocks to allocate
+ n_block_bytes: the size of each block in bytes
+ Returns: the allocated memory, or %NULL.
+ Since: 2.24
+
+
+<!-- ##### FUNCTION g_try_malloc0_n ##### -->
+<para>
+This function is similar to g_try_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
+but care is taken to detect possible overflow during multiplication.
+</para>
+
+ n_blocks: the number of blocks to allocate
+ n_block_bytes: the size of each block in bytes
+ Returns: the allocated memory, or %NULL
+ Since: 2.24
+
+
+<!-- ##### FUNCTION g_try_realloc_n ##### -->
+<para>
+This function is similar to g_try_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
+but care is taken to detect possible overflow during multiplication.
+</para>
+
+ mem: previously-allocated memory, or %NULL.
+ n_blocks: the number of blocks to allocate
+ n_block_bytes: the size of each block in bytes
+ Returns: the allocated memory, or %NULL.
+ Since: 2.24
+
+
 <!-- ##### FUNCTION g_free ##### -->
 <para>
 Frees the memory pointed to by @mem.
diff --git a/glib/glib.symbols b/glib/glib.symbols
index 4baec9f..bc5d514 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -720,13 +720,19 @@ g_markup_collect_attributes
 g_free
 g_malloc G_GNUC_MALLOC
 g_malloc0 G_GNUC_MALLOC
+g_malloc_n G_GNUC_MALLOC
+g_malloc0_n G_GNUC_MALLOC
 g_mem_is_system_malloc
 g_mem_profile
 g_mem_set_vtable
 g_realloc
+g_realloc_n
 g_try_malloc G_GNUC_MALLOC
 g_try_malloc0 G_GNUC_MALLOC
+g_try_malloc_n G_GNUC_MALLOC
+g_try_malloc0_n G_GNUC_MALLOC
 g_try_realloc
+g_try_realloc_n
 #ifndef G_DISABLE_DEPRECATED
 g_allocator_free
 g_allocator_new
diff --git a/glib/gmem.c b/glib/gmem.c
index 54d6008..0f190fc 100644
--- a/glib/gmem.c
+++ b/glib/gmem.c
@@ -203,11 +203,11 @@ g_try_malloc (gsize n_bytes)
 
 gpointer
 g_try_malloc0 (gsize n_bytes)
-{ 
+{
   gpointer mem;
 
   mem = g_try_malloc (n_bytes);
-  
+
   if (mem)
     memset (mem, 0, n_bytes);
 
@@ -229,6 +229,97 @@ g_try_realloc (gpointer mem,
   return NULL;
 }
 
+
+#define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((a) > G_MAXSIZE / (b)))
+
+#undef g_malloc_n
+gpointer
+g_malloc_n (gsize n_blocks,
+	    gsize n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    {
+      if (G_UNLIKELY (!g_mem_initialized))
+	g_mem_init_nomessage();
+
+      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_blocks, n_block_bytes);
+    }
+
+  return g_malloc (n_blocks * n_block_bytes);
+}
+
+#undef g_malloc0_n
+gpointer
+g_malloc0_n (gsize n_blocks,
+	     gsize n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    {
+      if (G_UNLIKELY (!g_mem_initialized))
+	g_mem_init_nomessage();
+
+      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_blocks, n_block_bytes);
+    }
+
+  return g_malloc0 (n_blocks * n_block_bytes);
+}
+
+#undef g_realloc_n
+gpointer
+g_realloc_n (gpointer mem,
+	     gsize    n_blocks,
+	     gsize    n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    {
+      if (G_UNLIKELY (!g_mem_initialized))
+	g_mem_init_nomessage();
+
+      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_blocks, n_block_bytes);
+    }
+
+  return g_realloc (mem, n_blocks * n_block_bytes);
+}
+
+#undef g_try_malloc_n
+gpointer
+g_try_malloc_n (gsize n_blocks,
+		gsize n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    return NULL;
+
+  return g_try_malloc (n_blocks * n_block_bytes);
+}
+
+#undef g_try_malloc0_n
+gpointer
+g_try_malloc0_n (gsize n_blocks,
+		 gsize n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    return NULL;
+
+  return g_try_malloc0 (n_blocks * n_block_bytes);
+}
+
+#undef g_try_realloc_n
+gpointer
+g_try_realloc_n (gpointer mem,
+		 gsize    n_blocks,
+		 gsize    n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    return NULL;
+
+  return g_try_realloc (mem, n_blocks * n_block_bytes);
+}
+
+
+
 static gpointer
 fallback_calloc (gsize n_blocks,
 		 gsize n_block_bytes)
diff --git a/glib/gmem.h b/glib/gmem.h
index 8cb050e..fc5d95d 100644
--- a/glib/gmem.h
+++ b/glib/gmem.h
@@ -48,40 +48,102 @@ typedef struct _GMemVTable GMemVTable;
 
 /* Memory allocation functions
  */
+
+void	 g_free	          (gpointer	 mem);
+
 gpointer g_malloc         (gsize	 n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
 gpointer g_malloc0        (gsize	 n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
 gpointer g_realloc        (gpointer	 mem,
 			   gsize	 n_bytes) G_GNUC_WARN_UNUSED_RESULT;
-void	 g_free	          (gpointer	 mem);
 gpointer g_try_malloc     (gsize	 n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
 gpointer g_try_malloc0    (gsize	 n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
 gpointer g_try_realloc    (gpointer	 mem,
 			   gsize	 n_bytes) G_GNUC_WARN_UNUSED_RESULT;
 
+gpointer g_malloc_n       (gsize	 n_blocks,
+			   gsize	 n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2);
+gpointer g_malloc0_n      (gsize	 n_blocks,
+			   gsize	 n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2);
+gpointer g_realloc_n      (gpointer	 mem,
+			   gsize	 n_blocks,
+			   gsize	 n_block_bytes) G_GNUC_WARN_UNUSED_RESULT;
+gpointer g_try_malloc_n   (gsize	 n_blocks,
+			   gsize	 n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2);
+gpointer g_try_malloc0_n  (gsize	 n_blocks,
+			   gsize	 n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2);
+gpointer g_try_realloc_n  (gpointer	 mem,
+			   gsize	 n_blocks,
+			   gsize	 n_block_bytes) G_GNUC_WARN_UNUSED_RESULT;
+
+
+/* avoid the overflow check if we can determine at compile-time that no
+ * overflow happens. */
+#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__)
+#  define _G_MALLOC_N(n_blocks, n_block_bytes, func_1, func_n) \
+	(__extension__ ({					\
+	  gsize __a = (gsize) (n_blocks);			\
+	  gsize __b = (gsize) (n_block_bytes);			\
+	  gpointer __p;						\
+	  if (__builtin_constant_p (__a) && __a == 1)		\
+	    __p = func_1 (__b);					\
+	  else if (__builtin_constant_p (__b) && __b == 1)	\
+	    __p = func_1 (__a);					\
+	  else if (__builtin_constant_p (__a) &&		\
+		   __builtin_constant_p (__b) &&		\
+		   __a <= G_MAXSIZE / __b)			\
+	    __p = func_1 (__a * __b);				\
+	  else							\
+	    __p = func_n (__a, __b);				\
+	  __p;							\
+	}))
+#  define _G_REALLOC_N(mem, n_blocks, n_block_bytes, func_1, func_n) \
+	(__extension__ ({					\
+	  gsize __a = (gsize) (n_blocks);			\
+	  gsize __b = (gsize) (n_block_bytes);			\
+	  gpointer __p = (gpointer) (mem);			\
+	  if (__builtin_constant_p (__a) && __a == 1)		\
+	    __p = func_1 (__p, __b);				\
+	  else if (__builtin_constant_p (__b) && __b == 1)	\
+	    __p = func_1 (__p, __a);				\
+	  else if (__builtin_constant_p (__a) &&		\
+		   __builtin_constant_p (__b) &&		\
+		   __a <= G_MAXSIZE / __b)			\
+	    __p = func_1 (__p, __a * __b);			\
+	  else							\
+	    __p = func_n (__p, __a, __b);			\
+	  __p;							\
+	}))
+
+#  define g_malloc_n(n_blocks,n_block_bytes)		_G_MALLOC_N (n_blocks, n_block_bytes, g_malloc, g_malloc_n)
+#  define g_malloc0_n(n_blocks,n_block_bytes)		_G_MALLOC_N (n_blocks, n_block_bytes, g_malloc0, g_malloc0_n)
+#  define g_realloc_n(mem,n_blocks,n_block_bytes)	_G_REALLOC_N (mem, n_blocks, n_block_bytes, g_realloc, g_realloc_n)
+#  define g_try_malloc_n(n_blocks,n_block_bytes)	_G_MALLOC_N (n_blocks, n_block_bytes, g_try_malloc, g_try_malloc_n)
+#  define g_try_malloc0_n(n_blocks,n_block_bytes)	_G_MALLOC_N (n_blocks, n_block_bytes, g_try_malloc0, g_try_malloc0_n)
+#  define g_try_realloc_n(mem,n_blocks,n_block_bytes)	_G_REALLOC_N (mem, n_blocks, n_block_bytes, g_try_realloc, g_try_realloc_n)
+#endif
+
 
 /* Convenience memory allocators
  */
-#define g_new(struct_type, n_structs)		\
-    ((struct_type *) g_malloc (((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
-#define g_new0(struct_type, n_structs)		\
-    ((struct_type *) g_malloc0 (((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
-#define g_renew(struct_type, mem, n_structs)	\
-    ((struct_type *) g_realloc ((mem), ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
 
-#define g_try_new(struct_type, n_structs)		\
-    ((struct_type *) g_try_malloc (((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
-#define g_try_new0(struct_type, n_structs)		\
-    ((struct_type *) g_try_malloc0 (((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
-#define g_try_renew(struct_type, mem, n_structs)	\
-    ((struct_type *) g_try_realloc ((mem), ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+#define _G_NEW(struct_type, n_structs, _g_malloc_n)	\
+	((struct_type *) _g_malloc_n ((n_structs), sizeof (struct_type)))
+#define _G_RENEW(struct_type, mem, n_structs, _g_realloc_n)	\
+	((struct_type *) _g_realloc_n ((mem), (n_structs), sizeof (struct_type)))
+
+#define g_new(struct_type, n_structs)			_G_NEW (struct_type, n_structs, g_malloc_n)
+#define g_new0(struct_type, n_structs)			_G_NEW (struct_type, n_structs, g_malloc0_n)
+#define g_renew(struct_type, mem, n_structs)		_G_RENEW (struct_type, mem, n_structs, g_realloc_n)
+#define g_try_new(struct_type, n_structs)		_G_NEW (struct_type, n_structs, g_try_malloc_n)
+#define g_try_new0(struct_type, n_structs)		_G_NEW (struct_type, n_structs, g_try_malloc0_n)
+#define g_try_renew(struct_type, mem, n_structs)	_G_RENEW (struct_type, mem, n_structs, g_try_realloc_n)
 
 
 /* Memory allocation virtualization for debugging purposes
  * g_mem_set_vtable() has to be the very first GLib function called
  * if being used
  */
-struct _GMemVTable
-{
+struct _GMemVTable {
   gpointer (*malloc)      (gsize    n_bytes);
   gpointer (*realloc)     (gpointer mem,
 			   gsize    n_bytes);
diff --git a/glib/tests/Makefile.am b/glib/tests/Makefile.am
index c271891..1b0d940 100644
--- a/glib/tests/Makefile.am
+++ b/glib/tests/Makefile.am
@@ -50,6 +50,9 @@ hostutils_LDADD     = $(progs_ldadd)
 TEST_PROGS         += gvariant
 gvariant_LDADD      = $(progs_ldadd)
 
+TEST_PROGS         += mem-overflow
+mem_overflow_LDADD  = $(progs_ldadd)
+
 if OS_UNIX
 
 # some testing of gtester funcitonality
diff --git a/glib/tests/mem-overflow.c b/glib/tests/mem-overflow.c
new file mode 100644
index 0000000..f78c7b7
--- /dev/null
+++ b/glib/tests/mem-overflow.c
@@ -0,0 +1,108 @@
+/* Unit tests for g
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This work is provided "as is"; redistribution and modification
+ * in whole or in part, in any medium, physical or electronic is
+ * permitted without restriction.
+ *
+ * This work 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.
+ *
+ * In no event shall the authors or contributors be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential
+ * damages (including, but not limited to, procurement of substitute
+ * goods or services; loss of use, data, or profits; or business
+ * interruption) however caused and on any theory of liability, whether
+ * in contract, strict liability, or tort (including negligence or
+ * otherwise) arising in any way out of the use of this software, even
+ * if advised of the possibility of such damage.
+ */
+
+#include "glib.h"
+#include <stdlib.h>
+
+static void
+mem_overflow (void)
+{
+  gsize a = G_MAXSIZE / 10 + 10;
+  gsize b = 10;
+  gpointer p, q;
+  typedef char X[10];
+
+#define CHECK_PASS(P)	p = (P); g_assert (p == NULL);
+#define CHECK_FAIL(P)	p = (P); g_assert (p != NULL);
+
+  CHECK_PASS (g_try_malloc_n (a, a));
+  CHECK_PASS (g_try_malloc_n (a, b));
+  CHECK_PASS (g_try_malloc_n (b, a));
+  CHECK_FAIL (g_try_malloc_n (b, b));
+
+  CHECK_PASS (g_try_malloc0_n (a, a));
+  CHECK_PASS (g_try_malloc0_n (a, b));
+  CHECK_PASS (g_try_malloc0_n (b, a));
+  CHECK_FAIL (g_try_malloc0_n (b, b));
+
+  q = g_malloc (1);
+  CHECK_PASS (g_try_realloc_n (q, a, a));
+  CHECK_PASS (g_try_realloc_n (q, a, b));
+  CHECK_PASS (g_try_realloc_n (q, b, a));
+  CHECK_FAIL (g_try_realloc_n (q, b, b));
+  free (p);
+
+  CHECK_PASS (g_try_new (X, a));
+  CHECK_FAIL (g_try_new (X, b));
+
+  CHECK_PASS (g_try_new0 (X, a));
+  CHECK_FAIL (g_try_new0 (X, b));
+
+  q = g_try_malloc (1);
+  CHECK_PASS (g_try_renew (X, q, a));
+  CHECK_FAIL (g_try_renew (X, q, b));
+  free (p);
+
+#undef CHECK_EQ
+#undef CHECK_NEQ
+
+#define CHECK_FAIL(P)	if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR)) { p = (P); exit (0); } g_test_trap_assert_failed();
+#define CHECK_PASS(P)	if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR)) { p = (P); exit (0); } g_test_trap_assert_passed();
+
+  CHECK_FAIL (g_malloc_n (a, a));
+  CHECK_FAIL (g_malloc_n (a, b));
+  CHECK_FAIL (g_malloc_n (b, a));
+  CHECK_PASS (g_malloc_n (b, b));
+
+  CHECK_FAIL (g_malloc0_n (a, a));
+  CHECK_FAIL (g_malloc0_n (a, b));
+  CHECK_FAIL (g_malloc0_n (b, a));
+  CHECK_PASS (g_malloc0_n (b, b));
+
+  q = g_malloc (1);
+  CHECK_FAIL (g_realloc_n (q, a, a));
+  CHECK_FAIL (g_realloc_n (q, a, b));
+  CHECK_FAIL (g_realloc_n (q, b, a));
+  CHECK_PASS (g_realloc_n (q, b, b));
+  free (q);
+
+  CHECK_FAIL (g_new (X, a));
+  CHECK_PASS (g_new (X, b));
+
+  CHECK_FAIL (g_new0 (X, a));
+  CHECK_PASS (g_new0 (X, b));
+
+  q = g_malloc (1);
+  CHECK_FAIL (g_renew (X, q, a));
+  CHECK_PASS (g_renew (X, q, b));
+  free (q);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/mem/overflow", mem_overflow);
+
+  return g_test_run();
+}
diff --git a/glib/tests/printf.c b/glib/tests/printf.c
index ff8eee2..a8ab0dc 100644
--- a/glib/tests/printf.c
+++ b/glib/tests/printf.c
@@ -1,4 +1,4 @@
-/* Unit tests for gstring
+/* Unit tests for gprintf
  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
  *
  * This work is provided "as is"; redistribution and modification
diff --git a/glib/tests/rand.c b/glib/tests/rand.c
index 0bddfbf..62b5f75 100644
--- a/glib/tests/rand.c
+++ b/glib/tests/rand.c
@@ -1,4 +1,4 @@
-/* Unit tests for gstring
+/* Unit tests for grand
  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
  *
  * This work is provided "as is"; redistribution and modification



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