Loading src/common/util.c +67 −0 Changes for src/common/util.c: 67 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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 * ===== */ Loading src/common/util.h +4 −0 Changes for src/common/util.h: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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); Loading src/test/test_util.c +50 −0 Changes for src/test/test_util.c: 50 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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), Loading Loading
src/common/util.c +67 −0 Changes for src/common/util.c: 67 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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 * ===== */ Loading
src/common/util.h +4 −0 Changes for src/common/util.h: 4 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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); Loading
src/test/test_util.c +50 −0 Changes for src/test/test_util.c: 50 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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), Loading