From a332805a55ce750ea3238b4e758a7542d0afcd1b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 29 Dec 2008 16:54:56 +0000 Subject: [PATCH] Extact parse-the-token-arguments to its own function, and change it to a single-pass algorithm. This simplifies the parsing code and speeds it up a little. svn:r17812 --- src/or/routerparse.c | 58 ++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/or/routerparse.c b/src/or/routerparse.c index a0929c9c86..e0bbac003f 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -2919,6 +2919,37 @@ token_check_object(memarea_t *area, const char *kwd, return tok; } +/** Helper: parse space-separated arguments from the string s ending at + * eol, and store them in the args field of tok. Store the + * number of parsed elements into the n_args field of tok. Allocate + * all storage in area. Return the number of arguments parsed, or + * return -1 if there was an insanely high number of arguments. */ +static INLINE int +get_token_arguments(memarea_t *area, directory_token_t *tok, + const char *s, const char *eol) +{ +/** Largest number of arguments we'll accept to any token, ever. */ +#define MAX_ARGS 512 + char *mem = memarea_strndup(area, s, eol-s); + char *cp = mem; + int j = 0; + char *args[MAX_ARGS]; + while (*cp) { + if (j == MAX_ARGS) + return -1; + args[j++] = cp; + cp = (char*)find_whitespace(cp); + if (!cp || !*cp) + break; /* End of the line. */ + *cp++ = '\0'; + cp = (char*)eat_whitespace(cp); + } + tok->n_args = j; + tok->args = memarea_memdup(area, args, j*sizeof(char*)); + return j; +#undef MAX_ARGS +} + /** Helper function: read the next token from *s, advance *s to the end of the * token, and return the parsed token. Parse *s according to the list * of tokens in table. @@ -2973,30 +3004,9 @@ get_next_token(memarea_t *area, tok->n_args = 1; } else { /* This keyword takes multiple arguments. */ - /* XXXX021 this code is still too complicated. */ - char *mem = memarea_strndup(area, *s, eol-*s); - char *cp = mem; - int j = 0; - while (*cp) { - j++; - cp = (char*)find_whitespace(cp); - if (!cp || !*cp) - break; - cp = (char*)eat_whitespace(cp); - } - tok->n_args = j; - if (tok->n_args) { - tok->args = memarea_alloc(area, sizeof(char*)*tok->n_args); - cp = mem; - j = 0; - while (*cp) { - tok->args[j++] = cp; - cp = (char*)find_whitespace(cp); - if (!cp || !*cp) - break; - *cp++ = '\0'; - cp = (char*)eat_whitespace(cp); - } + if (get_token_arguments(area, tok, *s, eol)<0) { + tor_snprintf(ebuf, sizeof(ebuf),"Far too many arguments to %s", kwd); + RET_ERR(ebuf); } *s = eol; }