This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Fix strtok/strtok_r (generic version)
- To: libc-alpha at sources dot redhat dot com
- Subject: Fix strtok/strtok_r (generic version)
- From: Andreas Jaeger <aj at suse dot de>
- Date: 23 Feb 2001 10:21:04 +0100
- Cc: Fumitoshi UKAI <ukai at debian dot or dot jp>
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