Loading ChangeLog +5 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,11 @@ Changes in version 0.2.0.16-alpha - 2008-01-?? implementation also avoids realloc();realloc(); patterns that can contribute to memory fragmentation. o Minor features: - Configuration files now accept C-style strings as values. This helps encode characters not allowed in the current configuration file format, such as newline or #. Addresses bug 557. o Minor performance improvements: - Reference-count and share copies of address policy entries; only 5% of them were actually distinct. Loading doc/tor.1.in +3 −2 Original line number Diff line number Diff line Loading @@ -53,8 +53,9 @@ Display Tor version. .LP .TP Other options can be specified either on the command-line (\fI--option value\fR), or in the configuration file (\fIoption value\fR). Options are case-insensitive. value\fR), or in the configuration file (\fIoption value\fR or \fIoption "value"\fR). Options are case-insensitive. C-style escaped characters are allowed inside quoted values. .LP .TP \fBBandwidthRate \fR\fIN\fR \fBbytes\fR|\fBKB\fR|\fBMB\fR|\fBGB\fR|\fBTB\fP Loading src/common/util.c +109 −13 Original line number Diff line number Diff line Loading @@ -1924,6 +1924,95 @@ read_file_to_str(const char *filename, int flags, struct stat *stat_out) return string; } #define TOR_ISODIGIT(c) ('0' <= (c) && (c) <= '7') /* DOCDOC */ static const char * unescape_string(const char *s, char **result, size_t *size_out) { const char *cp; char *out; tor_assert(s[0] == '\"'); cp = s+1; while (1) { switch (*cp) { case '\0': case '\n': return NULL; case '\"': goto end_of_loop; case '\\': if ((cp[1] == 'x' || cp[1] == 'X') && TOR_ISXDIGIT(cp[2]) && TOR_ISXDIGIT(cp[3])) { cp += 4; } else if (TOR_ISODIGIT(cp[1])) { cp += 2; if (TOR_ISODIGIT(*cp)) ++cp; if (TOR_ISODIGIT(*cp)) ++cp; } else if (cp[1]) { cp += 2; } else { return NULL; } break; default: ++cp; break; } } end_of_loop: out = *result = tor_malloc(cp-s + 1); cp = s+1; while (1) { switch (*cp) { case '\"': *out = '\0'; if (size_out) *size_out = out - *result; return cp+1; case '\0': tor_fragile_assert(); tor_free(*result); return NULL; case '\\': switch (cp[1]) { case 'n': *out++ = '\n'; cp += 2; break; case 'r': *out++ = '\r'; cp += 2; break; case 't': *out++ = '\t'; cp += 2; break; case 'x': case 'X': *out++ = ((hex_decode_digit(cp[2])<<4) + hex_decode_digit(cp[3])); cp += 4; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { int n = cp[1]-'0'; cp += 2; if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; } if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; } if (n > 255) { tor_free(*result); return NULL; } *out++ = (char)n; } break; case '\'': case '\"': case '\\': case '\?': *out++ = cp[1]; cp += 2; break; default: tor_free(*result); return NULL; } break; default: *out++ = *cp++; } } } /** Given a string containing part of a configuration file or similar format, * advance past comments and whitespace and try to parse a single line. If we * parse a line successfully, set *<b>key_out</b> to a new string holding the Loading Loading @@ -1965,13 +2054,20 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out) ++line; *key_out = tor_strndup(key, line-key); /* Skip until the value, writing nuls so key will be nul-terminated */ /* Skip until the value. */ while (*line == ' ' || *line == '\t') ++line; val = line; /* Find the end of the line. */ if (*line == '\"') { line = unescape_string(line, value_out, NULL); while (*line == ' ' || *line == '\t') ++line; if (*line && *line != '#' && *line != '\n') return NULL; } else { while (*line && *line != '\n' && *line != '#') ++line; if (*line == '\n') { Loading @@ -1984,14 +2080,14 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out) tor_assert(cp >= val); *value_out = tor_strndup(val, cp-val); } if (*line == '#') { do { ++line; } while (*line && *line != '\n'); if (*line == '\n') ++line; } while(TOR_ISSPACE(*line)) ++line; return line; } Loading src/or/test.c +18 −3 Original line number Diff line number Diff line Loading @@ -826,7 +826,10 @@ test_util(void) strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n" "k2\n" "k3 \n" "\n" " \n" "#comment\n" "k4#a\n" "k5#abc\n" "k6 val #with comment\n", sizeof(buf)); "k4#a\n" "k5#abc\n" "k6 val #with comment\n" "kseven \"a quoted 'string\"\n" "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n" , sizeof(buf)); str = buf; str = parse_config_line_from_str(str, &k, &v); Loading Loading @@ -857,7 +860,7 @@ test_util(void) test_streq(k, "k3"); test_streq(v, ""); tor_free(k); tor_free(v); test_assert(!strcmpstart(str, "\n \n")); test_assert(!strcmpstart(str, "#comment")); str = parse_config_line_from_str(str, &k, &v); test_streq(k, "k4"); Loading @@ -875,6 +878,18 @@ test_util(void) test_streq(k, "k6"); test_streq(v, "val"); tor_free(k); tor_free(v); test_assert(!strcmpstart(str, "kseven")); str = parse_config_line_from_str(str, &k, &v); test_streq(k, "kseven"); test_streq(v, "a quoted 'string"); tor_free(k); tor_free(v); test_assert(!strcmpstart(str, "k8 ")); str = parse_config_line_from_str(str, &k, &v); test_streq(k, "k8"); test_streq(v, "a quoted\n\"str\\ing\t\x01\x01\x01\""); tor_free(k); tor_free(v); test_streq(str, ""); /* Test for strcmpstart and strcmpend. */ Loading Loading
ChangeLog +5 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,11 @@ Changes in version 0.2.0.16-alpha - 2008-01-?? implementation also avoids realloc();realloc(); patterns that can contribute to memory fragmentation. o Minor features: - Configuration files now accept C-style strings as values. This helps encode characters not allowed in the current configuration file format, such as newline or #. Addresses bug 557. o Minor performance improvements: - Reference-count and share copies of address policy entries; only 5% of them were actually distinct. Loading
doc/tor.1.in +3 −2 Original line number Diff line number Diff line Loading @@ -53,8 +53,9 @@ Display Tor version. .LP .TP Other options can be specified either on the command-line (\fI--option value\fR), or in the configuration file (\fIoption value\fR). Options are case-insensitive. value\fR), or in the configuration file (\fIoption value\fR or \fIoption "value"\fR). Options are case-insensitive. C-style escaped characters are allowed inside quoted values. .LP .TP \fBBandwidthRate \fR\fIN\fR \fBbytes\fR|\fBKB\fR|\fBMB\fR|\fBGB\fR|\fBTB\fP Loading
src/common/util.c +109 −13 Original line number Diff line number Diff line Loading @@ -1924,6 +1924,95 @@ read_file_to_str(const char *filename, int flags, struct stat *stat_out) return string; } #define TOR_ISODIGIT(c) ('0' <= (c) && (c) <= '7') /* DOCDOC */ static const char * unescape_string(const char *s, char **result, size_t *size_out) { const char *cp; char *out; tor_assert(s[0] == '\"'); cp = s+1; while (1) { switch (*cp) { case '\0': case '\n': return NULL; case '\"': goto end_of_loop; case '\\': if ((cp[1] == 'x' || cp[1] == 'X') && TOR_ISXDIGIT(cp[2]) && TOR_ISXDIGIT(cp[3])) { cp += 4; } else if (TOR_ISODIGIT(cp[1])) { cp += 2; if (TOR_ISODIGIT(*cp)) ++cp; if (TOR_ISODIGIT(*cp)) ++cp; } else if (cp[1]) { cp += 2; } else { return NULL; } break; default: ++cp; break; } } end_of_loop: out = *result = tor_malloc(cp-s + 1); cp = s+1; while (1) { switch (*cp) { case '\"': *out = '\0'; if (size_out) *size_out = out - *result; return cp+1; case '\0': tor_fragile_assert(); tor_free(*result); return NULL; case '\\': switch (cp[1]) { case 'n': *out++ = '\n'; cp += 2; break; case 'r': *out++ = '\r'; cp += 2; break; case 't': *out++ = '\t'; cp += 2; break; case 'x': case 'X': *out++ = ((hex_decode_digit(cp[2])<<4) + hex_decode_digit(cp[3])); cp += 4; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { int n = cp[1]-'0'; cp += 2; if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; } if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; } if (n > 255) { tor_free(*result); return NULL; } *out++ = (char)n; } break; case '\'': case '\"': case '\\': case '\?': *out++ = cp[1]; cp += 2; break; default: tor_free(*result); return NULL; } break; default: *out++ = *cp++; } } } /** Given a string containing part of a configuration file or similar format, * advance past comments and whitespace and try to parse a single line. If we * parse a line successfully, set *<b>key_out</b> to a new string holding the Loading Loading @@ -1965,13 +2054,20 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out) ++line; *key_out = tor_strndup(key, line-key); /* Skip until the value, writing nuls so key will be nul-terminated */ /* Skip until the value. */ while (*line == ' ' || *line == '\t') ++line; val = line; /* Find the end of the line. */ if (*line == '\"') { line = unescape_string(line, value_out, NULL); while (*line == ' ' || *line == '\t') ++line; if (*line && *line != '#' && *line != '\n') return NULL; } else { while (*line && *line != '\n' && *line != '#') ++line; if (*line == '\n') { Loading @@ -1984,14 +2080,14 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out) tor_assert(cp >= val); *value_out = tor_strndup(val, cp-val); } if (*line == '#') { do { ++line; } while (*line && *line != '\n'); if (*line == '\n') ++line; } while(TOR_ISSPACE(*line)) ++line; return line; } Loading
src/or/test.c +18 −3 Original line number Diff line number Diff line Loading @@ -826,7 +826,10 @@ test_util(void) strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n" "k2\n" "k3 \n" "\n" " \n" "#comment\n" "k4#a\n" "k5#abc\n" "k6 val #with comment\n", sizeof(buf)); "k4#a\n" "k5#abc\n" "k6 val #with comment\n" "kseven \"a quoted 'string\"\n" "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n" , sizeof(buf)); str = buf; str = parse_config_line_from_str(str, &k, &v); Loading Loading @@ -857,7 +860,7 @@ test_util(void) test_streq(k, "k3"); test_streq(v, ""); tor_free(k); tor_free(v); test_assert(!strcmpstart(str, "\n \n")); test_assert(!strcmpstart(str, "#comment")); str = parse_config_line_from_str(str, &k, &v); test_streq(k, "k4"); Loading @@ -875,6 +878,18 @@ test_util(void) test_streq(k, "k6"); test_streq(v, "val"); tor_free(k); tor_free(v); test_assert(!strcmpstart(str, "kseven")); str = parse_config_line_from_str(str, &k, &v); test_streq(k, "kseven"); test_streq(v, "a quoted 'string"); tor_free(k); tor_free(v); test_assert(!strcmpstart(str, "k8 ")); str = parse_config_line_from_str(str, &k, &v); test_streq(k, "k8"); test_streq(v, "a quoted\n\"str\\ing\t\x01\x01\x01\""); tor_free(k); tor_free(v); test_streq(str, ""); /* Test for strcmpstart and strcmpend. */ Loading