This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Fix strtok/strtok_r (generic version)



Here's a proper fix for the strtok/strtok_r bug plus a testcase for
the regression suite.

HJ, I think this is a better way to fix the problem.

The i386 files in sysdeps/i386/strtok.S and sysdeps/i386/strtok_r.S
are also broken, I don't have a fix for them.

Thanks Fumitoshi for the fix.

Ok to commit?
Andreas

2001-02-23  Andreas Jaeger  <aj@suse.de>

	* string/tester.c (test_strtok_r): Add testcase.
	(test_strtok_r): Always initialize cp for proper checking.

	* sysdeps/generic/strtok.c (strtok): Handle case of first strtok
	returning NULL correctly.
	Patch by Fumitoshi UKAI <ukai@debian.or.jp>.
	* sysdeps/generic/strtok_r.c (__strtok_r): Likewise.

============================================================
Index: sysdeps/generic/strtok.c
--- sysdeps/generic/strtok.c	2000/08/15 06:07:55	1.8
+++ sysdeps/generic/strtok.c	2001/02/23 09:20:15
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1996,1997,1999,2000,2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -45,7 +45,10 @@
   /* Scan leading delimiters.  */
   s += strspn (s, delim);
   if (*s == '\0')
-    return NULL;
+    {
+      olds = s;
+      return NULL;
+    }
 
   /* Find the end of the token.  */
   token = s;
============================================================
Index: sysdeps/generic/strtok_r.c
--- sysdeps/generic/strtok_r.c	1999/05/03 23:48:29	1.9
+++ sysdeps/generic/strtok_r.c	2001/02/23 09:20:15
@@ -1,5 +1,5 @@
 /* Reentrant string tokenizer.  Generic version.
-   Copyright (C) 1991, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -46,7 +46,10 @@
   /* Scan leading delimiters.  */
   s += strspn (s, delim);
   if (*s == '\0')
-    return NULL;
+    {
+      *save_ptr = s;
+      return NULL;
+    }
 
   /* Find the end of the token.  */
   token = s;
============================================================
Index: string/tester.c
--- string/tester.c	2000/11/26 04:52:21	1.36
+++ string/tester.c	2001/02/23 09:20:17
@@ -1,5 +1,5 @@
 /* Tester for string functions.
-   Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1995-2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -759,23 +759,28 @@
 {
   it = "strtok_r";
   (void) strcpy(one, "first, second, third");
+  cp = NULL;	/* Always initialize cp to make sure it doesn't point to some old data.  */
   equal(strtok_r(one, ", ", &cp), "first", 1);	/* Basic test. */
   equal(one, "first", 2);
   equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
   equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
   (void) strcpy(one, ", first, ");
+  cp = NULL;
   equal(strtok_r(one, ", ", &cp), "first", 6);	/* Extra delims, 1 tok. */
   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
   (void) strcpy(one, "1a, 1b; 2a, 2b");
+  cp = NULL;
   equal(strtok_r(one, ", ", &cp), "1a", 8);	/* Changing delim lists. */
   equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
   equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
   (void) strcpy(two, "x-y");
+  cp = NULL;
   equal(strtok_r(two, "-", &cp), "x", 11);	/* New string before done. */
   equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
   check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
   (void) strcpy(one, "a,b, c,, ,d");
+  cp = NULL;
   equal(strtok_r(one, ", ", &cp), "a", 14);	/* Different separators. */
   equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
   equal(strtok_r((char *)NULL, " ,", &cp), "c", 16);	/* Permute list too. */
@@ -783,25 +788,31 @@
   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
   check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19);	/* Persistence. */
   (void) strcpy(one, ", ");
+  cp = NULL;
   check(strtok_r(one, ", ", &cp) == NULL, 20);	/* No tokens. */
   (void) strcpy(one, "");
+  cp = NULL;
   check(strtok_r(one, ", ", &cp) == NULL, 21);	/* Empty string. */
+  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22);	/* Persistence. */
   (void) strcpy(one, "abc");
-  equal(strtok_r(one, ", ", &cp), "abc", 22);	/* No delimiters. */
-  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 23);
+  cp = NULL;
+  equal(strtok_r(one, ", ", &cp), "abc", 23);	/* No delimiters. */
+  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
   (void) strcpy(one, "abc");
-  equal(strtok_r(one, "", &cp), "abc", 24);	/* Empty delimiter list. */
-  check(strtok_r((char *)NULL, "", &cp) == NULL, 25);
+  cp = NULL;
+  equal(strtok_r(one, "", &cp), "abc", 25);	/* Empty delimiter list. */
+  check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
   (void) strcpy(one, "abcdefgh");
   (void) strcpy(one, "a,b,c");
-  equal(strtok_r(one, ",", &cp), "a", 26);	/* Basics again... */
-  equal(strtok_r((char *)NULL, ",", &cp), "b", 27);
-  equal(strtok_r((char *)NULL, ",", &cp), "c", 28);
-  check(strtok_r((char *)NULL, ",", &cp) == NULL, 29);
-  equal(one+6, "gh", 30);			/* Stomped past end? */
-  equal(one, "a", 31);			/* Stomped old tokens? */
-  equal(one+2, "b", 32);
-  equal(one+4, "c", 33);
+  cp = NULL;
+  equal(strtok_r(one, ",", &cp), "a", 27);	/* Basics again... */
+  equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
+  equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
+  check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
+  equal(one+6, "gh", 31);			/* Stomped past end? */
+  equal(one, "a", 32);			/* Stomped old tokens? */
+  equal(one+2, "b", 33);
+  equal(one+4, "c", 34);
 }
 
 static void

-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.inka.de
    http://www.suse.de/~aj


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]