Re: patch to change behavior of g_strsplit on empty string back to 1.2 behavior



I did more testing, and found a buffer overrun problem in g_strsplit too in cases where the string ends in a delimiter. Here's the patch with that fixed (also attached to the bug report).

OK to commit?

Index: glib/gstrfuncs.c
===================================================================
RCS file: /cvs/gnome/glib/glib/gstrfuncs.c,v
retrieving revision 1.61
diff -p -u -r1.61 gstrfuncs.c
--- glib/gstrfuncs.c	2001/07/12 09:23:38	1.61
+++ glib/gstrfuncs.c	2001/07/17 16:16:11
@@ -1569,15 +1569,18 @@ g_strsplit (const gchar *string,
 {
   GSList *string_list = NULL, *slist;
   gchar **str_array, *s;
-  guint n = 1;
+  guint n = 0;
+  const gchar *remainder;

   g_return_val_if_fail (string != NULL, NULL);
   g_return_val_if_fail (delimiter != NULL, NULL);
+  g_return_val_if_fail (delimiter[0] != '\0', NULL);

   if (max_tokens < 1)
     max_tokens = G_MAXINT;

-  s = strstr (string, delimiter);
+  remainder = string;
+  s = strstr (remainder, delimiter);
   if (s)
     {
       gsize delimiter_len = strlen (delimiter);
@@ -1587,18 +1590,22 @@ g_strsplit (const gchar *string,
 	  gsize len;
 	  gchar *new_string;

-	  len = s - string;
+	  len = s - remainder;
 	  new_string = g_new (gchar, len + 1);
-	  strncpy (new_string, string, len);
+	  strncpy (new_string, remainder, len);
 	  new_string[len] = 0;
 	  string_list = g_slist_prepend (string_list, new_string);
 	  n++;
-	  string = s + delimiter_len;
-	  s = strstr (string, delimiter);
+	  remainder = s + delimiter_len;
+	  s = strstr (remainder, delimiter);
 	}
       while (--max_tokens && s);
     }
-  string_list = g_slist_prepend (string_list, g_strdup (string));
+  if (*string && max_tokens)
+    {
+      n++;
+      string_list = g_slist_prepend (string_list, g_strdup (remainder));
+    }

   str_array = g_new (gchar*, n + 1);

Index: tests/.cvsignore
===================================================================
RCS file: /cvs/gnome/glib/tests/.cvsignore,v
retrieving revision 1.26
diff -p -u -r1.26 .cvsignore
--- tests/.cvsignore	2001/07/02 00:49:21	1.26
+++ tests/.cvsignore	2001/07/17 16:16:11
@@ -17,6 +17,7 @@ cxx-test
 date-test
 dirname-test
 hash-test
+iochannel-test
 list-test
 mainloop-test
 markup-test
Index: tests/array-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/array-test.c,v
retrieving revision 1.3
diff -p -u -r1.3 array-test.c
--- tests/array-test.c	2000/07/26 11:02:02	1.3
+++ tests/array-test.c	2001/07/17 16:16:11
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>
Index: tests/dirname-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/dirname-test.c,v
retrieving revision 1.5
diff -p -u -r1.5 dirname-test.c
--- tests/dirname-test.c	2000/07/26 11:02:02	1.5
+++ tests/dirname-test.c	2001/07/17 16:16:12
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>
Index: tests/hash-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/hash-test.c,v
retrieving revision 1.7
diff -p -u -r1.7 hash-test.c
--- tests/hash-test.c	2000/10/30 14:34:52	1.7
+++ tests/hash-test.c	2001/07/17 16:16:12
@@ -25,6 +25,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #ifdef HAVE_CONFIG_H
Index: tests/list-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/list-test.c,v
retrieving revision 1.4
diff -p -u -r1.4 list-test.c
--- tests/list-test.c	2000/07/26 11:02:02	1.4
+++ tests/list-test.c	2001/07/17 16:16:12
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>
Index: tests/node-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/node-test.c,v
retrieving revision 1.6
diff -p -u -r1.6 node-test.c
--- tests/node-test.c	2000/07/26 11:02:02	1.6
+++ tests/node-test.c	2001/07/17 16:16:12
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #ifdef HAVE_CONFIG_H
Index: tests/relation-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/relation-test.c,v
retrieving revision 1.3
diff -p -u -r1.3 relation-test.c
--- tests/relation-test.c	2000/07/26 11:02:02	1.3
+++ tests/relation-test.c	2001/07/17 16:16:13
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>
Index: tests/shell-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/shell-test.c,v
retrieving revision 1.2
diff -p -u -r1.2 shell-test.c
--- tests/shell-test.c	2000/11/28 23:44:21	1.2
+++ tests/shell-test.c	2001/07/17 16:16:13
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <glib.h>
Index: tests/slist-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/slist-test.c,v
retrieving revision 1.4
diff -p -u -r1.4 slist-test.c
--- tests/slist-test.c	2000/07/26 11:02:02	1.4
+++ tests/slist-test.c	2001/07/17 16:16:13
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>
Index: tests/spawn-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/spawn-test.c,v
retrieving revision 1.2
diff -p -u -r1.2 spawn-test.c
--- tests/spawn-test.c	2000/10/16 18:54:29	1.2
+++ tests/spawn-test.c	2001/07/17 16:16:13
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <glib.h>
Index: tests/strfunc-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/strfunc-test.c,v
retrieving revision 1.7
diff -p -u -r1.7 strfunc-test.c
--- tests/strfunc-test.c	2001/06/08 23:14:03	1.7
+++ tests/strfunc-test.c	2001/07/17 16:16:13
@@ -24,11 +24,13 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>
 #include <string.h>
 #include "glib.h"
+#include <stdarg.h>

 int array[10000];
 gboolean failed = FALSE;
@@ -55,6 +57,35 @@ typedef struct {
 	gchar name[40];
 } GlibTestInfo;

+static gboolean
+strv_check (gchar **strv, ...)
+{
+  gboolean ok = TRUE;
+  gint i = 0;
+  va_list list;
+
+  va_start (list, strv);
+  while (ok)
+    {
+      const gchar *str = va_arg (list, const char *);
+      if (strv[i] == NULL)
+	{
+	  ok = str == NULL;
+	  break;
+	}
+      if (str == NULL)
+	ok = FALSE;
+      else if (strcmp (strv[i], str) != 0)
+	ok = FALSE;
+      i++;
+    }
+  va_end (list);
+
+  g_strfreev (strv);
+
+  return ok;
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -63,20 +94,20 @@ main (int   argc,
   gchar *vec[] = { "Foo", "Bar", NULL };
   gchar **copy;

-  g_assert (g_strcasecmp ("FroboZZ", "frobozz") == 0);
-  g_assert (g_strcasecmp ("frobozz", "frobozz") == 0);
-  g_assert (g_strcasecmp ("frobozz", "FROBOZZ") == 0);
-  g_assert (g_strcasecmp ("FROBOZZ", "froboz") != 0);
-  g_assert (g_strcasecmp ("", "") == 0);
-  g_assert (g_strcasecmp ("!#%&/()", "!#%&/()") == 0);
-  g_assert (g_strcasecmp ("a", "b") < 0);
-  g_assert (g_strcasecmp ("a", "B") < 0);
-  g_assert (g_strcasecmp ("A", "b") < 0);
-  g_assert (g_strcasecmp ("A", "B") < 0);
-  g_assert (g_strcasecmp ("b", "a") > 0);
-  g_assert (g_strcasecmp ("b", "A") > 0);
-  g_assert (g_strcasecmp ("B", "a") > 0);
-  g_assert (g_strcasecmp ("B", "A") > 0);
+  g_assert (g_ascii_strcasecmp ("FroboZZ", "frobozz") == 0);
+  g_assert (g_ascii_strcasecmp ("frobozz", "frobozz") == 0);
+  g_assert (g_ascii_strcasecmp ("frobozz", "FROBOZZ") == 0);
+  g_assert (g_ascii_strcasecmp ("FROBOZZ", "froboz") != 0);
+  g_assert (g_ascii_strcasecmp ("", "") == 0);
+  g_assert (g_ascii_strcasecmp ("!#%&/()", "!#%&/()") == 0);
+  g_assert (g_ascii_strcasecmp ("a", "b") < 0);
+  g_assert (g_ascii_strcasecmp ("a", "B") < 0);
+  g_assert (g_ascii_strcasecmp ("A", "b") < 0);
+  g_assert (g_ascii_strcasecmp ("A", "B") < 0);
+  g_assert (g_ascii_strcasecmp ("b", "a") > 0);
+  g_assert (g_ascii_strcasecmp ("b", "A") > 0);
+  g_assert (g_ascii_strcasecmp ("B", "a") > 0);
+  g_assert (g_ascii_strcasecmp ("B", "A") > 0);

   g_assert(g_strdup(NULL) == NULL);
   string = g_strdup(GLIB_TEST_STRING);
@@ -123,8 +154,32 @@ main (int   argc,
 		    "BarFoo") == 0);
   g_assert (strcmp (g_strrstr_len ("FooBarFooBarFoo", 14, "BarFoo"),
 		    "BarFooBarFoo") == 0);
-  return 0;
-}
-

+  g_assert (strv_check (g_strsplit ("", ",", 0), NULL));
+  g_assert (strv_check (g_strsplit ("x", ",", 0), "x", NULL));
+  g_assert (strv_check (g_strsplit ("x,y", ",", 0), "x", "y", NULL));
+  g_assert (strv_check (g_strsplit ("x,y,", ",", 0), "x", "y", "", NULL))
;
+  g_assert (strv_check (g_strsplit (",x,y", ",", 0), "", "x", "y", NULL))
;
+ g_assert (strv_check (g_strsplit (",x,y,", ",", 0), "", "x", "y", "", NULL));
+  g_assert (strv_check (g_strsplit ("x,y,z", ",", 0), "x", "y", "z", NULL)
);
+ g_assert (strv_check (g_strsplit ("x,y,z,", ",", 0), "x", "y", "z", "", NULL)); + g_assert (strv_check (g_strsplit (",x,y,z", ",", 0), "", "x", "y", "z", NULL));
+  g_assert (strv_check (g_strsplit (",x,y,z,", ",", 0), "", "x", "y", "z"
, "", NULL));
+ g_assert (strv_check (g_strsplit (",,x,,y,,z,,", ",", 0), "", "", "x", "", "y", "", "z", "", "", NULL));
+  g_assert (strv_check (g_strsplit (",,x,,y,,z,,", ",,", 0), "", "x", "y"
, "z", "", NULL));
+
+  g_assert (strv_check (g_strsplit ("", ",", 2), NULL));
+  g_assert (strv_check (g_strsplit ("x", ",", 2), "x", NULL));
+  g_assert (strv_check (g_strsplit ("x,y", ",", 2), "x", "y", NULL));
+  g_assert (strv_check (g_strsplit ("x,y,", ",", 2), "x", "y", NULL));
+  g_assert (strv_check (g_strsplit (",x,y", ",", 2), "", "x", NULL));
+  g_assert (strv_check (g_strsplit (",x,y,", ",", 2), "", "x", NULL));
+  g_assert (strv_check (g_strsplit ("x,y,z", ",", 2), "x", "y", NULL));
+  g_assert (strv_check (g_strsplit ("x,y,z,", ",", 2), "x", "y", NULL));
+  g_assert (strv_check (g_strsplit (",x,y,z", ",", 2), "", "x", NULL));
+  g_assert (strv_check (g_strsplit (",x,y,z,", ",", 2), "", "x", NULL));
+  g_assert (strv_check (g_strsplit (",,x,,y,,z,,", ",", 2), "", "", NULL)
);
+ g_assert (strv_check (g_strsplit (",,x,,y,,z,,", ",,", 2), "", "x", NULL));

+  return 0;
+}
Index: tests/string-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/string-test.c,v
retrieving revision 1.10
diff -p -u -r1.10 string-test.c
--- tests/string-test.c	2000/07/26 11:02:02	1.10
+++ tests/string-test.c	2001/07/17 16:16:13
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>
Index: tests/testglib.c
===================================================================
RCS file: /cvs/gnome/glib/tests/testglib.c,v
retrieving revision 1.52
diff -p -u -r1.52 testglib.c
--- tests/testglib.c	2001/07/11 20:08:50	1.52
+++ tests/testglib.c	2001/07/17 16:16:14
@@ -26,6 +26,7 @@

 #include "config.h"

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #ifdef GLIB_COMPILATION
Index: tests/tree-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/tree-test.c,v
retrieving revision 1.3
diff -p -u -r1.3 tree-test.c
--- tests/tree-test.c	2000/07/26 11:02:02	1.3
+++ tests/tree-test.c	2001/07/17 16:16:14
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>
Index: tests/type-test.c
===================================================================
RCS file: /cvs/gnome/glib/tests/type-test.c,v
retrieving revision 1.6
diff -p -u -r1.6 type-test.c
--- tests/type-test.c	2001/04/20 17:08:57	1.6
+++ tests/type-test.c	2001/07/17 16:16:14
@@ -24,6 +24,7 @@
  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  */

+#undef G_DISABLE_ASSERT
 #undef G_LOG_DOMAIN

 #include <stdio.h>

===================================================================

    -- Darin




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