diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/util.c | 42 | ||||
-rw-r--r-- | src/common/util.h | 3 |
2 files changed, 23 insertions, 22 deletions
diff --git a/src/common/util.c b/src/common/util.c index 24037c10b2..5ff97273a8 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1926,23 +1926,22 @@ read_file_to_str(const char *filename, int flags, struct stat *stat_out) /** 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 the key portion and - * *<b>value_out</b> to the value portion of the line, and return a pointer to - * the start of the next line. If we run out of data, return a pointer to the - * end of the string. If we encounter an error, return NULL. - * - * NOTE: We modify *<b>line</b> as we parse it, by inserting NULs - * to terminate the key and value. + * parse a line successfully, set *<b>key_out</b> to a new string holding the + * key portion and *<b>value_out</b> to a new string holding the value portion + * of the line, and return a pointer to the start of the next line. If we run + * out of data, return a pointer to the end of the string. If we encounter an + * error, return NULL. */ -char * -parse_line_from_str(char *line, char **key_out, char **value_out) +const char * +parse_config_line_from_str(const char *line, char **key_out, char **value_out) { - char *key, *val, *cp; + const char *key, *val, *cp; tor_assert(key_out); tor_assert(value_out); - *key_out = *value_out = key = val = NULL; + *key_out = *value_out = NULL; + key = val = NULL; /* Skip until the first keyword. */ while (1) { while (TOR_ISSPACE(*line)) @@ -1964,35 +1963,36 @@ parse_line_from_str(char *line, char **key_out, char **value_out) key = line; while (*line && !TOR_ISSPACE(*line) && *line != '#') ++line; + *key_out = tor_strndup(key, line-key); /* Skip until the value, writing nuls so key will be nul-terminated */ while (*line == ' ' || *line == '\t') - *line++ = '\0'; + ++line; val = line; /* Find the end of the line. */ while (*line && *line != '\n' && *line != '#') ++line; - if (*line == '\n') + if (*line == '\n') { cp = line++; - else { - cp = line-1; + } else { + cp = line; } - while (cp>=val && TOR_ISSPACE(*cp)) - *cp-- = '\0'; + while (cp>val && TOR_ISSPACE(*(cp-1))) + --cp; + + tor_assert(cp >= val); + *value_out = tor_strndup(val, cp-val); if (*line == '#') { do { - *line++ = '\0'; + ++line; } while (*line && *line != '\n'); if (*line == '\n') ++line; } - *key_out = key; - *value_out = val; - return line; } diff --git a/src/common/util.h b/src/common/util.h index d69c919964..1eaad82ec2 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -265,7 +265,8 @@ int append_bytes_to_file(const char *fname, const char *str, size_t len, struct stat; char *read_file_to_str(const char *filename, int flags, struct stat *stat_out) ATTR_MALLOC; -char *parse_line_from_str(char *line, char **key_out, char **value_out); +const char *parse_config_line_from_str(const char *line, + char **key_out, char **value_out); char *expand_filename(const char *filename); struct smartlist_t *tor_listdir(const char *dirname); int path_is_relative(const char *filename) ATTR_PURE; |