mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 13:43:47 +01:00
Add utility functions needed for SOCKS argument parsing.
This commit is contained in:
parent
d86a45f991
commit
b8532bcb1e
@ -865,6 +865,36 @@ tor_digest_is_zero(const char *digest)
|
|||||||
return tor_memeq(digest, ZERO_DIGEST, DIGEST_LEN);
|
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. */
|
/** Return true iff the DIGEST256_LEN bytes in digest are all zero. */
|
||||||
int
|
int
|
||||||
tor_digest256_is_zero(const char *digest)
|
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
|
* Time
|
||||||
* ===== */
|
* ===== */
|
||||||
|
@ -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 *find_str_at_start_of_line(const char *haystack,
|
||||||
const char *needle);
|
const char *needle);
|
||||||
int string_is_C_identifier(const char *string);
|
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_mem_is_zero(const char *mem, size_t len);
|
||||||
int tor_digest_is_zero(const char *digest);
|
int tor_digest_is_zero(const char *digest);
|
||||||
int tor_digest256_is_zero(const char *digest);
|
int tor_digest256_is_zero(const char *digest);
|
||||||
char *esc_for_log(const char *string) ATTR_MALLOC;
|
char *esc_for_log(const char *string) ATTR_MALLOC;
|
||||||
const char *escaped(const char *string);
|
const char *escaped(const char *string);
|
||||||
|
|
||||||
|
char *tor_escape_str_for_socks_arg(const char *string);
|
||||||
|
|
||||||
struct smartlist_t;
|
struct smartlist_t;
|
||||||
void wrap_string(struct smartlist_t *out, const char *string, size_t width,
|
void wrap_string(struct smartlist_t *out, const char *string, size_t width,
|
||||||
const char *prefix0, const char *prefixRest);
|
const char *prefix0, const char *prefixRest);
|
||||||
|
@ -795,6 +795,54 @@ test_util_expand_filename(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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. */
|
/** Test basic string functionality. */
|
||||||
static void
|
static void
|
||||||
test_util_strmisc(void)
|
test_util_strmisc(void)
|
||||||
@ -3271,6 +3319,8 @@ struct testcase_t util_tests[] = {
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
UTIL_LEGACY(expand_filename),
|
UTIL_LEGACY(expand_filename),
|
||||||
#endif
|
#endif
|
||||||
|
UTIL_LEGACY(escape_string_socks),
|
||||||
|
UTIL_LEGACY(string_is_key_value),
|
||||||
UTIL_LEGACY(strmisc),
|
UTIL_LEGACY(strmisc),
|
||||||
UTIL_LEGACY(pow2),
|
UTIL_LEGACY(pow2),
|
||||||
UTIL_LEGACY(gzip),
|
UTIL_LEGACY(gzip),
|
||||||
|
Loading…
Reference in New Issue
Block a user