mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
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:
parent
56e0959d2a
commit
efb8a09f41
4
changes/bug5091
Normal file
4
changes/bug5091
Normal 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.
|
@ -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,
|
||||
};
|
||||
|
||||
/** 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
|
||||
* how to write one. Hey guys! You can use this code here for free! */
|
||||
char *
|
||||
tor_strtok_r_impl(char *str, const char *sep, char **lasts)
|
||||
{
|
||||
char *cp, *start;
|
||||
if (str)
|
||||
start = cp = *lasts = str;
|
||||
else if (!*lasts)
|
||||
return NULL;
|
||||
else
|
||||
start = cp = *lasts;
|
||||
|
||||
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]) {
|
||||
while (*cp && !strchr(sep, *cp))
|
||||
++cp;
|
||||
} else {
|
||||
tor_assert(strlen(sep) == 1);
|
||||
cp = strchr(cp, *sep);
|
||||
}
|
||||
|
||||
@ -572,7 +590,7 @@ tor_strtok_r_impl(char *str, const char *sep, char **lasts)
|
||||
*lasts = NULL;
|
||||
} else {
|
||||
*cp++ = '\0';
|
||||
*lasts = cp;
|
||||
*lasts = strtok_helper(cp, sep);
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
@ -1735,32 +1735,56 @@ test_util_strtok(void)
|
||||
{
|
||||
char buf[128];
|
||||
char buf2[128];
|
||||
int i;
|
||||
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));
|
||||
/* -- "Year's End", Richard Wilbur */
|
||||
|
||||
test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
|
||||
test_streq("they", tor_strtok_r_impl(buf2, ".!..;!", &cp2));
|
||||
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 */
|
||||
|
||||
test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
|
||||
test_streq("they", tor_strtok_r_impl(buf2, ".!..;!", &cp2));
|
||||
#define S1() tor_strtok_r_impl(NULL, " ", &cp1)
|
||||
#define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
|
||||
test_streq("on", S1());
|
||||
test_streq("the", S1());
|
||||
test_streq("dark", S1());
|
||||
test_streq("seemed", S2());
|
||||
test_streq("their", S2());
|
||||
test_streq("own", S2());
|
||||
test_streq("in", S1());
|
||||
test_streq("gestures", S1());
|
||||
test_streq("of", S1());
|
||||
test_streq("most", S2());
|
||||
test_streq("perfect", S2());
|
||||
test_streq("descent", S1());
|
||||
test_streq("monument", S2());
|
||||
test_eq_ptr(NULL, S1());
|
||||
test_eq_ptr(NULL, S2());
|
||||
test_streq("on", S1());
|
||||
test_streq("the", S1());
|
||||
test_streq("dark", S1());
|
||||
test_streq("seemed", S2());
|
||||
test_streq("their", S2());
|
||||
test_streq("own", S2());
|
||||
test_streq("in", S1());
|
||||
test_streq("gestures", S1());
|
||||
test_streq("of", S1());
|
||||
test_streq("most", S2());
|
||||
test_streq("perfect", S2());
|
||||
test_streq("descent", S1());
|
||||
test_streq("monument", S2());
|
||||
test_eq_ptr(NULL, S1());
|
||||
test_eq_ptr(NULL, S2());
|
||||
}
|
||||
|
||||
#if 0
|
||||
buf[0] = 0;
|
||||
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));
|
||||
strlcpy(buf, " ", sizeof(buf));
|
||||
test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
|
||||
#endif
|
||||
|
||||
strlcpy(buf, "something ", sizeof(buf));
|
||||
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:
|
||||
;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user