[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] [tor/master 5/6] Tweak continuation-and-comment logic
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Thu, 23 Sep 2010 22:58:04 -0400
Subject: Tweak continuation-and-comment logic
Commit: 0a0cc4599fd743d124d6ee90671c7c8e205b86e8
I think there was a read-off-the-end-of-the-buffer bug that I fixed.
At least I added some good comments, I hope.
---
changes/torrc_continuation | 2 +-
src/common/util.c | 46 ++++++++++++++++++++++++++++++++++++++++---
2 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/changes/torrc_continuation b/changes/torrc_continuation
index f63937e..5b6e086 100644
--- a/changes/torrc_continuation
+++ b/changes/torrc_continuation
@@ -2,5 +2,5 @@
- Support line continuations in torrc. If a line ends with a
single backslash character, the newline is ignored, and the
configuration value is treated as continuing on the next line.
- Implements bug 1929.
+ Resolves bug 1929.
diff --git a/src/common/util.c b/src/common/util.c
index e47ac78..904fd82 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2284,6 +2284,36 @@ unescape_string(const char *s, char **result, size_t *size_out)
const char *
parse_config_line_from_str(const char *line, char **key_out, char **value_out)
{
+ /* I believe the file format here is supposed to be:
+ FILE = (EMPTYLINE | LINE)*
+
+ EMPTYLINE = SPACE* NL | COMMENT NL
+ SPACE = ' ' | '\r' | '\t'
+ COMMENT = '#' NOT-NL*
+ NOT-NL = Any character except '\n'
+ NL = '\n'
+
+ LINE = SPACE* KEY SPACE* VALUES NL
+ KEY = KEYCHAR+
+ KEYCHAR = Any character except ' ', '\r', '\n', '\t', '#', "\"
+
+ VALUES = QUOTEDVALUE | NORMALVALUE
+ QUOTEDVALUE = QUOTE QVITEM* QUOTE EOLSPACE?
+ QUOTE = '"'
+ QVCHAR = KEYCHAR | ESC ('n' | 't' | 'r' | '"' | ESC |'\'' | OCTAL | HEX)
+ ESC = "\\"
+ OCTAL = ODIGIT (ODIGIT ODIGIT?)?
+ HEX = ('x' | 'X') HEXDIGIT HEXDIGIT
+ ODIGIT = '0' .. '7'
+ HEXDIGIT = '0'..'9' | 'a' .. 'f' | 'A' .. 'F'
+ EOLSPACE = SPACE* COMMENT?
+
+ NORMALVALUE = (VALCHAR | ESC ESC_IGNORE | CONTINUATION)* EOLSPACE?
+ VALCHAR = Any character except ESC, '#', and '\n'
+ ESC_IGNORE = Any character except '#' or '\n'
+ CONTINUATION = ESC NL ( COMMENT NL )*
+ */
+
const char *key, *val, *cp;
int continuation = 0;
@@ -2323,7 +2353,7 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out)
val = line;
/* Find the end of the line. */
- if (*line == '\"') { // XXX No continuation here
+ if (*line == '\"') { // XXX No continuation handling is done here
if (!(line = unescape_string(line, value_out, NULL)))
return NULL;
while (*line == ' ' || *line == '\t')
@@ -2331,27 +2361,34 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out)
if (*line && *line != '#' && *line != '\n')
return NULL;
} else {
+ /* Look for the end of the line. */
while (*line && *line != '\n' && (*line != '#' || continuation)) {
if (*line == '\\' && line[1] == '\n') {
continuation = 1;
- ++line;
+ line += 2;
} else if (*line == '#') {
do {
++line;
} while (*line && *line != '\n');
+ if (*line == '\n')
+ ++line;
+ } else {
+ ++line;
}
- ++line;
}
+
if (*line == '\n') {
cp = line++;
} else {
cp = line;
}
+ /* Now back cp up to be the last nonspace character */
while (cp>val && TOR_ISSPACE(*(cp-1)))
--cp;
tor_assert(cp >= val);
+ /* Now copy out and decode the value. */
*value_out = tor_strndup(val, cp-val);
if (continuation) {
char *v_out, *v_in;
@@ -2361,7 +2398,8 @@ parse_config_line_from_str(const char *line, char **key_out, char **value_out)
do {
++v_in;
} while (*v_in && *v_in != '\n');
- ++v_in;
+ if (*v_in == '\n')
+ ++v_in;
} else if (v_in[0] == '\\' && v_in[1] == '\n') {
v_in += 2;
} else {
--
1.7.1