Add utility functions needed for SOCKS argument parsing.

This commit is contained in:
George Kadianakis 2012-12-17 14:14:09 +02:00
parent d86a45f991
commit b8532bcb1e
3 changed files with 121 additions and 0 deletions

View File

@ -865,6 +865,36 @@ tor_digest_is_zero(const char *digest)
return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
}
/** Return true if <b>string</b> is a valid '<key>=<value>' string.
* <value> is optional, to indicate the empty string. */
int
string_is_key_value(const char *string)
{
/* position of equal sign in string */
char *equal_sign_pos = NULL;
tor_assert(string);
if (strlen(string) < 2) { /* "x=a" is shortest args string */
log_warn(LD_GENERAL, "'%s' is too short to be a k=v value.", string);
return 0;
}
equal_sign_pos = strchr(string, '=');
if (!equal_sign_pos) {
log_warn(LD_GENERAL, "'%s' is not a k=v value.", string);
return 0;
}
/* validate that the '=' is not in the beginning of the string. */
if (equal_sign_pos == string) {
log_warn(LD_GENERAL, "'%s' is not a valid k=v value.", string);
return 0;
}
return 1;
}
/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
int
tor_digest256_is_zero(const char *digest)
@ -1249,6 +1279,43 @@ wrap_string(smartlist_t *out, const char *string, size_t width,
}
}
/** Escape every character of <b>string</b> that belongs to the set of
* characters <b>set</b>. Use <b>escape_char</b> as the character to
* use for escaping. */
char *
tor_escape_str_for_socks_arg(const char *string)
{
char *new_string = NULL;
char *new_cp = NULL;
size_t length, new_length;
static const char *chars_to_escape = ";\\";
tor_assert(string);
length = strlen(string);
if (!length)
return NULL;
/* (new_length > SIZE_MAX) => ((length * 2) + 1 > SIZE_MAX) =>
(length*2 > SIZE_MAX - 1) => (length > (SIZE_MAX - 1)/2) */
if (length > (SIZE_MAX - 1)/2) /* check for overflow */
return NULL;
/* this should be enough even if all characters must be escaped */
new_length = (length * 2) + 1;
new_string = new_cp = tor_malloc_zero(new_length);
while (*string) {
if (strchr(chars_to_escape, *string))
*new_cp++ = '\\';
*new_cp++ = *string++;
}
return new_string;
}
/* =====
* Time
* ===== */

View File

@ -209,12 +209,16 @@ const char *find_whitespace_eos(const char *s, const char *eos);
const char *find_str_at_start_of_line(const char *haystack,
const char *needle);
int string_is_C_identifier(const char *string);
int string_is_key_value(const char *string);
int tor_mem_is_zero(const char *mem, size_t len);
int tor_digest_is_zero(const char *digest);
int tor_digest256_is_zero(const char *digest);
char *esc_for_log(const char *string) ATTR_MALLOC;
const char *escaped(const char *string);
char *tor_escape_str_for_socks_arg(const char *string);
struct smartlist_t;
void wrap_string(struct smartlist_t *out, const char *string, size_t width,
const char *prefix0, const char *prefixRest);

View File

@ -795,6 +795,54 @@ test_util_expand_filename(void)
}
#endif
/** Test tor_escape_str_for_socks_arg(). */
static void
test_util_escape_string_socks(void)
{
char *escaped_string = NULL;
/** Simple backslash escape. */
escaped_string = tor_escape_str_for_socks_arg("This is a backslash: \\");
test_assert(escaped_string);
test_streq(escaped_string, "This is a backslash: \\\\");
tor_free(escaped_string);
/** Simple semicolon escape. */
escaped_string = tor_escape_str_for_socks_arg("First rule: Do not use ;");
test_assert(escaped_string);
test_streq(escaped_string, "First rule: Do not use \\;");
tor_free(escaped_string);
/** Ilegal: Empty string. */
escaped_string = tor_escape_str_for_socks_arg("");
test_assert(!escaped_string);
/** Escape all characters. */
escaped_string = tor_escape_str_for_socks_arg(";\\;\\");
test_assert(escaped_string);
test_streq(escaped_string, "\\;\\\\\\;\\\\");
tor_free(escaped_string);
done:
tor_free(escaped_string);
}
static void
test_util_string_is_key_value(void *ptr)
{
(void)ptr;
test_assert(string_is_key_value("key=value"));
test_assert(string_is_key_value("k=v"));
test_assert(string_is_key_value("key="));
test_assert(!string_is_key_value("=value"));
test_assert(!string_is_key_value("="));
/* ??? */
/* test_assert(!string_is_key_value("===")); */
done:
;
}
/** Test basic string functionality. */
static void
test_util_strmisc(void)
@ -3271,6 +3319,8 @@ struct testcase_t util_tests[] = {
#ifndef _WIN32
UTIL_LEGACY(expand_filename),
#endif
UTIL_LEGACY(escape_string_socks),
UTIL_LEGACY(string_is_key_value),
UTIL_LEGACY(strmisc),
UTIL_LEGACY(pow2),
UTIL_LEGACY(gzip),