aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/bug50914
-rw-r--r--src/common/compat.c30
-rw-r--r--src/test/test_util.c70
3 files changed, 74 insertions, 30 deletions
diff --git a/changes/bug5091 b/changes/bug5091
new file mode 100644
index 000000000..b9778d7b1
--- /dev/null
+++ b/changes/bug5091
@@ -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.
diff --git a/src/common/compat.c b/src/common/compat.c
index 30bde3d1c..bd6822517 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -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)
+ tor_assert(*sep);
+ if (str) {
+ str = strtok_helper(str, sep);
+ if (!*str)
+ return NULL;
start = cp = *lasts = str;
- else if (!*lasts)
+ } else if (!*lasts || !**lasts) {
return NULL;
- else
+ } else {
start = cp = *lasts;
+ }
- tor_assert(*sep);
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;
}
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 88f00e071..3cbc5bf89 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -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:
;
}