summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2017-05-26 18:42:05 +0200
committerJo-Philipp Wich <jo@mein.io>2017-05-26 18:52:28 +0200
commit3d2c18a91bb7cd5f3c0dec7fecf3008934de170b (patch)
tree3dcf10fa98db75b3c0d6febf8e32a3d449da2bd2
parent0e5dd73076c3dc23a6971784640dd7e36f99b6d5 (diff)
downloadfirewall3-3d2c18a91bb7cd5f3c0dec7fecf3008934de170b.tar.gz
options: improve handling of negations when parsing space separated values
Improve the space separated list parser to interprete "val1 ! val2" as ("val1", "!val2") instead of ("val1", "!", "val2"). This corrects parsing of sections like ... config rule option sec_ip '! 1.1.1.0/24' ... which previously errored out with: Warning: Option @rule[0].src_ip has invalid value '!' Fixes FS#806. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--options.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/options.c b/options.c
index d88d3ba..ae6bf5d 100644
--- a/options.c
+++ b/options.c
@@ -891,7 +891,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
struct uci_section *section)
{
char *p, *v;
- bool known;
+ bool known, inv;
struct uci_element *e, *l;
struct uci_option *o;
const struct fw3_option *opt;
@@ -953,10 +953,30 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
}
else
{
+ inv = false;
dest = (struct list_head *)((char *)s + opt->offset);
for (p = strtok(v, " \t"); p != NULL; p = strtok(NULL, " \t"))
{
+ /* If we encounter a sole "!" token, assume that it
+ * is meant to be part of the next token, so silently
+ * skip it and remember the state... */
+ if (!strcmp(p, "!"))
+ {
+ inv = true;
+ continue;
+ }
+
+ /* The previous token was a sole "!", rewind pointer
+ * back by one byte to precede the value with an
+ * exclamation mark which effectively turns
+ * ("!", "foo") into ("!foo") */
+ if (inv)
+ {
+ *--p = '!';
+ inv = false;
+ }
+
if (!opt->parse(dest, p, true))
{
warn_elem(e, "has invalid value '%s'", p);
@@ -964,6 +984,15 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
continue;
}
}
+
+ /* The last token was a sole "!" without any subsequent
+ * text, so pass it to the option parser as-is. */
+ if (inv && !opt->parse(dest, "!", true))
+ {
+ warn_elem(e, "has invalid value '%s'", p);
+ valid = false;
+ continue;
+ }
}
}