aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/util.c42
-rw-r--r--src/common/util.h3
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;