mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Add a new tor_strtok_r for platforms that don't have one, plus tests.
I don't think we actually use (or plan to use) strtok_r in a reentrant way anywhere in our code, but would be nice not to have to think about whether we're doing it.
This commit is contained in:
@@ -398,6 +398,37 @@ const char TOR_TOLOWER_TABLE[256] = {
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
|
||||
};
|
||||
|
||||
/** 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 (sep[1]) {
|
||||
while (*cp && !strchr(sep, *cp))
|
||||
++cp;
|
||||
} else {
|
||||
tor_assert(strlen(sep) == 1);
|
||||
cp = strchr(cp, *sep);
|
||||
}
|
||||
|
||||
if (!cp || !*cp) {
|
||||
*lasts = NULL;
|
||||
} else {
|
||||
*cp++ = '\0';
|
||||
*lasts = cp;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/** Take a filename and return a pointer to its final element. This
|
||||
* function is called on __FILE__ to fix a MSVC nit where __FILE__
|
||||
|
||||
@@ -267,6 +267,13 @@ extern const char TOR_TOLOWER_TABLE[];
|
||||
#define TOR_TOLOWER(c) (TOR_TOLOWER_TABLE[(uint8_t)c])
|
||||
#define TOR_TOUPPER(c) (TOR_TOUPPER_TABLE[(uint8_t)c])
|
||||
|
||||
char *tor_strtok_r_impl(char *str, const char *sep, char **lasts);
|
||||
#ifdef HAVE_STRTOK_R
|
||||
#define tor_strok_r(str, sep, lasts) strtok_r(str, sep, lasts)
|
||||
#else
|
||||
#define tor_strok_r(str, sep, lasts) tor_strtok_r_impl(str, sep, lasts)
|
||||
#endif
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
#define _SHORT_FILE_ (tor_fix_source_file(__FILE__))
|
||||
const char *tor_fix_source_file(const char *fname);
|
||||
|
||||
@@ -4284,6 +4284,39 @@ test_util_datadir(void)
|
||||
tor_free(f);
|
||||
}
|
||||
|
||||
static void
|
||||
test_util_strtok(void)
|
||||
{
|
||||
char buf[128];
|
||||
char buf2[128];
|
||||
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));
|
||||
#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_assert(NULL == S1());
|
||||
test_assert(NULL == S2());
|
||||
done:
|
||||
;
|
||||
}
|
||||
|
||||
/** Test AES-CTR encryption and decryption with IV. */
|
||||
static void
|
||||
test_crypto_aes_iv(void)
|
||||
@@ -4692,6 +4725,7 @@ static struct {
|
||||
SUBENT(util, threads),
|
||||
SUBENT(util, order_functions),
|
||||
SUBENT(util, sscanf),
|
||||
SUBENT(util, strtok),
|
||||
ENT(onion_handshake),
|
||||
ENT(dir_format),
|
||||
ENT(dirutil),
|
||||
|
||||
Reference in New Issue
Block a user