[tor-commits] [tor/master] Make a parse_config_line_from_str variant that gives error messages

nickm at torproject.org nickm at torproject.org
Tue Mar 19 19:33:12 UTC 2013


commit 1827be0bd6a400f4b5970f5b37b1d2c8e83b6a3f
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Feb 19 17:32:15 2013 -0500

    Make a parse_config_line_from_str variant that gives error messages
    
    Without this patch, there's no way to know what went wrong when we
    fail to parse a torrc line entirely (that is, we can't turn it into
    a K,V pair.)  This patch introduces a new function that yields an
    error message on failure, so we can at least tell the user what to
    look for in their nonfunctional torrc.
    
    (Actually, it's the same function as before with a new name:
    parse_config_line_from_str is now a wrapper macro that the unit
    tests use.)
    
    Fixes bug 7950; fix on 0.2.0.16-alpha (58de695f9062576f) which first
    introduced the possibility of a torrc value not parsing correctly.
---
 changes/bug7950    |    4 ++++
 src/common/util.c  |   19 ++++++++++++++-----
 src/common/util.h  |    7 +++++--
 src/or/confparse.c |    5 ++++-
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/changes/bug7950 b/changes/bug7950
new file mode 100644
index 0000000..e62cca0
--- /dev/null
+++ b/changes/bug7950
@@ -0,0 +1,4 @@
+  o Minor bugfixes:
+    - When rejecting a configuration because we were unable to parse a
+      quoted string, log an actual error message. Fix for bug 7950;
+      bugfix on 0.2.0.16-alpha.
diff --git a/src/common/util.c b/src/common/util.c
index 6a69635..5f045d5 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2537,10 +2537,13 @@ unescape_string(const char *s, char **result, size_t *size_out)
  * 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.
+ * error, return NULL and set *<b>err_out</b> (if provided) to an error
+ * message.
  */
 const char *
-parse_config_line_from_str(const char *line, char **key_out, char **value_out)
+parse_config_line_from_str_verbose(const char *line, char **key_out,
+                                   char **value_out,
+                                   const char **err_out)
 {
   /* I believe the file format here is supposed to be:
      FILE = (EMPTYLINE | LINE)* (EMPTYLASTLINE | LASTLINE)?
@@ -2614,12 +2617,18 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out)
 
   /* Find the end of the line. */
   if (*line == '\"') { // XXX No continuation handling is done here
-    if (!(line = unescape_string(line, value_out, NULL)))
-       return NULL;
+    if (!(line = unescape_string(line, value_out, NULL))) {
+      if (err_out)
+        *err_out = "Invalid escape sequence in quoted string";
+      return NULL;
+    }
     while (*line == ' ' || *line == '\t')
       ++line;
-    if (*line && *line != '#' && *line != '\n')
+    if (*line && *line != '#' && *line != '\n') {
+      if (err_out)
+        *err_out = "Excess data after quoted string";
       return NULL;
+    }
   } else {
     /* Look for the end of the line. */
     while (*line && *line != '\n' && (*line != '#' || continuation)) {
diff --git a/src/common/util.h b/src/common/util.h
index ac88f1c..0123a53 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -375,8 +375,11 @@ char *read_file_to_str(const char *filename, int flags, struct stat *stat_out)
 char *read_file_to_str_until_eof(int fd, size_t max_bytes_to_read,
                                  size_t *sz_out)
   ATTR_MALLOC;
-const char *parse_config_line_from_str(const char *line,
-                                       char **key_out, char **value_out);
+const char *parse_config_line_from_str_verbose(const char *line,
+                                       char **key_out, char **value_out,
+                                       const char **err_out);
+#define parse_config_line_from_str(line,key_out,value_out) \
+  parse_config_line_from_str_verbose((line),(key_out),(value_out),NULL)
 char *expand_filename(const char *filename);
 struct smartlist_t *tor_listdir(const char *dirname);
 int path_is_relative(const char *filename);
diff --git a/src/or/confparse.c b/src/or/confparse.c
index 717d4ac..98fde98 100644
--- a/src/or/confparse.c
+++ b/src/or/confparse.c
@@ -91,12 +91,15 @@ config_get_lines(const char *string, config_line_t **result, int extended)
 {
   config_line_t *list = NULL, **next;
   char *k, *v;
+  const char *parse_err;
 
   next = &list;
   do {
     k = v = NULL;
-    string = parse_config_line_from_str(string, &k, &v);
+    string = parse_config_line_from_str_verbose(string, &k, &v, &parse_err);
     if (!string) {
+      log_warn(LD_CONFIG, "Error while parsing configuration: %s",
+               parse_err?parse_err:"<unknown>");
       config_free_lines(list);
       tor_free(k);
       tor_free(v);





More information about the tor-commits mailing list