diff options
author | Nick Mathewson <nickm@torproject.org> | 2019-04-24 11:42:10 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2019-04-25 14:13:03 -0400 |
commit | a5cced2b7acf4fb1818d6cd84c09a9ffe4dd1e89 (patch) | |
tree | 19189081b1babbcfff54fd57ff96e7ea88522f8e /src/feature/control/control_cmd.c | |
parent | a0299cd240292d93b0f465bf1845a5e54889f61b (diff) | |
download | tor-a5cced2b7acf4fb1818d6cd84c09a9ffe4dd1e89.tar.gz tor-a5cced2b7acf4fb1818d6cd84c09a9ffe4dd1e89.zip |
Extract keyword argument checking from argument parsing.
Diffstat (limited to 'src/feature/control/control_cmd.c')
-rw-r--r-- | src/feature/control/control_cmd.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index da9a95fc5d..9afa734d86 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -113,6 +113,41 @@ string_array_contains_keyword(const char **array, const char *kwd) return false; } +/** Helper for argument parsing: check whether the keyword arguments just + * parsed in <b>result</b> were well-formed according to <b>syntax</b>. + * + * On success, return 0. On failure, return -1 and set *<b>error_out</b> + * to a newly allocated error string. + **/ +static int +kvline_check_keyword_args(const control_cmd_args_t *result, + const control_cmd_syntax_t *syntax, + char **error_out) +{ + if (result->kwargs == NULL) { + tor_asprintf(error_out, "Cannot parse keyword argument(s)"); + return -1; + } + + if (! syntax->allowed_keywords) { + /* All keywords are permitted. */ + return 0; + } + + /* Check for unpermitted arguments */ + const config_line_t *line; + for (line = result->kwargs; line; line = line->next) { + if (! string_array_contains_keyword(syntax->allowed_keywords, + line->key)) { + tor_asprintf(error_out, "Unrecognized keyword argument %s", + escaped(line->key)); + return -1; + } + } + + return 0; +} + /** * Helper: parse the arguments to a command according to <b>syntax</b>. On * success, set *<b>error_out</b> to NULL and return a newly allocated @@ -174,27 +209,17 @@ control_cmd_parse_args(const char *command, } if (n_args > syntax->max_args) { + /* We have extra arguments after the positional arguments, and we didn't + treat them as an error, so they must count as keyword arguments: Either + K=V pairs, or flags, or both. */ tor_assert(n_args == syntax->max_args + 1); tor_assert(syntax->accept_keywords); char *remainder = smartlist_pop_last(result->args); result->kwargs = kvline_parse(remainder, syntax->kvline_flags); tor_free(remainder); - if (result->kwargs == NULL) { - tor_asprintf(error_out, "Cannot parse keyword argument(s)"); + if (kvline_check_keyword_args(result, syntax, error_out) < 0) { goto err; } - if (syntax->allowed_keywords) { - /* Check for unpermitted arguments */ - const config_line_t *line; - for (line = result->kwargs; line; line = line->next) { - if (! string_array_contains_keyword(syntax->allowed_keywords, - line->key)) { - tor_asprintf(error_out, "Unrecognized keyword argument %s", - escaped(line->key)); - goto err; - } - } - } } tor_assert_nonfatal(*error_out == NULL); |