Fix tor_strtok_r_impl and test cases per bug #5091

==

Nick here. I tweaked this patch a little to make it apply cleanly to
master, to extract some common code into a function, and to replace
snprintf with tor_snprintf.

-- nickm
This commit is contained in:
nils 2012-03-30 11:01:21 -04:00 committed by Nick Mathewson
parent 56e0959d2a
commit efb8a09f41
3 changed files with 77 additions and 33 deletions

4
changes/bug5091 Normal file
View File

@ -0,0 +1,4 @@
o Minor bugfixes:
- Make our replacement implementation of strtok_r compatible with
the standard behavior of strtok_r. Patch by nils. Fixes bug
5091; bugfix on 0.2.2.1-alpha.

View File

@ -546,25 +546,43 @@ const char TOR_TOLOWER_TABLE[256] = {
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
}; };
/** Helper for tor_strtok_r_impl: Advances cp past all characters in
* <b>sep</b>, and returns its new value. */
static char *
strtok_helper(char *cp, const char *sep)
{
if (sep[1]) {
while (*cp && strchr(sep, *cp))
++cp;
} else {
while (*cp && *cp == *sep)
++cp;
}
return cp;
}
/** Implementation of strtok_r for platforms whose coders haven't figured out /** Implementation of strtok_r for platforms whose coders haven't figured out
* how to write one. Hey guys! You can use this code here for free! */ * how to write one. Hey guys! You can use this code here for free! */
char * char *
tor_strtok_r_impl(char *str, const char *sep, char **lasts) tor_strtok_r_impl(char *str, const char *sep, char **lasts)
{ {
char *cp, *start; char *cp, *start;
if (str)
start = cp = *lasts = str;
else if (!*lasts)
return NULL;
else
start = cp = *lasts;
tor_assert(*sep); tor_assert(*sep);
if (str) {
str = strtok_helper(str, sep);
if (!*str)
return NULL;
start = cp = *lasts = str;
} else if (!*lasts || !**lasts) {
return NULL;
} else {
start = cp = *lasts;
}
if (sep[1]) { if (sep[1]) {
while (*cp && !strchr(sep, *cp)) while (*cp && !strchr(sep, *cp))
++cp; ++cp;
} else { } else {
tor_assert(strlen(sep) == 1);
cp = strchr(cp, *sep); cp = strchr(cp, *sep);
} }
@ -572,7 +590,7 @@ tor_strtok_r_impl(char *str, const char *sep, char **lasts)
*lasts = NULL; *lasts = NULL;
} else { } else {
*cp++ = '\0'; *cp++ = '\0';
*lasts = cp; *lasts = strtok_helper(cp, sep);
} }
return start; return start;
} }

View File

@ -1735,9 +1735,33 @@ test_util_strtok(void)
{ {
char buf[128]; char buf[128];
char buf2[128]; char buf2[128];
int i;
char *cp1, *cp2; char *cp1, *cp2;
strlcpy(buf, "Graved on the dark in gestures of descent", sizeof(buf));
strlcpy(buf2, "they.seemed;their!own;most.perfect;monument", sizeof(buf2)); for (i = 0; i < 3; i++) {
const char *pad1, *pad2;
switch (i) {
case 0:
pad1 = pad2 = "";
break;
case 1:
pad1 = " ";
pad2 = "!";
break;
case 2:
pad1 = " ";
pad2 = ";!";
break;
}
tor_snprintf(buf, sizeof(buf), "%s", pad1);
tor_snprintf(buf2, sizeof(buf2), "%s", pad2);
test_assert(NULL == tor_strtok_r_impl(buf, " ", &cp1));
test_assert(NULL == tor_strtok_r_impl(buf2, ".!..;!", &cp2));
tor_snprintf(buf, sizeof(buf),
"%sGraved on the dark in gestures of descent%s", pad1, pad1);
tor_snprintf(buf2, sizeof(buf2),
"%sthey.seemed;;their!.own;most.perfect;monument%s",pad2,pad2);
/* -- "Year's End", Richard Wilbur */ /* -- "Year's End", Richard Wilbur */
test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1)); test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
@ -1759,8 +1783,8 @@ test_util_strtok(void)
test_streq("monument", S2()); test_streq("monument", S2());
test_eq_ptr(NULL, S1()); test_eq_ptr(NULL, S1());
test_eq_ptr(NULL, S2()); test_eq_ptr(NULL, S2());
}
#if 0
buf[0] = 0; buf[0] = 0;
test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1)); test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
test_eq_ptr(NULL, tor_strtok_r_impl(buf, "!", &cp1)); test_eq_ptr(NULL, tor_strtok_r_impl(buf, "!", &cp1));
@ -1773,12 +1797,10 @@ test_util_strtok(void)
test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1)); test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
strlcpy(buf, " ", sizeof(buf)); strlcpy(buf, " ", sizeof(buf));
test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1)); test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
#endif
strlcpy(buf, "something ", sizeof(buf)); strlcpy(buf, "something ", sizeof(buf));
test_streq("something", tor_strtok_r_impl(buf, " ", &cp1)); test_streq("something", tor_strtok_r_impl(buf, " ", &cp1));
test_streq(" ", tor_strtok_r_impl(NULL, ";", &cp1)); test_eq_ptr(NULL, tor_strtok_r_impl(NULL, ";", &cp1));
test_eq_ptr(NULL, tor_strtok_r_impl(NULL, " ", &cp1));
done: done:
; ;
} }