X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuci.git;a=blobdiff_plain;f=file.c;h=4f1392e32ca6cfce3fdb430c29aeef27c0572451;hp=85959729fe1e2370213b967854a180363901e4f6;hb=031b620e1f3a16078da45ce00352508764902786;hpb=ad92cae5b9be81c30f25ebc1cd6292b7a40889a9 diff --git a/file.c b/file.c index 8595972..4f1392e 100644 --- a/file.c +++ b/file.c @@ -53,165 +53,6 @@ static void uci_file_cleanup(struct uci_context *ctx) } -/* - * parse a character escaped by '\' - * returns true if the escaped character is to be parsed - * returns false if the escaped character is to be ignored - */ -static inline bool parse_backslash(struct uci_context *ctx, char **str) -{ - /* skip backslash */ - *str += 1; - - /* undecoded backslash at the end of line, fetch the next line */ - if (!**str) { - *str += 1; - uci_getln(ctx, *str - ctx->pctx->buf); - return false; - } - - /* FIXME: decode escaped char, necessary? */ - return true; -} - -/* - * move the string pointer forward until a non-whitespace character or - * EOL is reached - */ -static void skip_whitespace(struct uci_context *ctx, char **str) -{ -restart: - while (**str && isspace(**str)) - *str += 1; - - if (**str == '\\') { - if (!parse_backslash(ctx, str)) - goto restart; - } -} - -static inline void addc(char **dest, char **src) -{ - **dest = **src; - *dest += 1; - *src += 1; -} - -/* - * parse a double quoted string argument from the command line - */ -static void parse_double_quote(struct uci_context *ctx, char **str, char **target) -{ - char c; - - /* skip quote character */ - *str += 1; - - while ((c = **str)) { - switch(c) { - case '"': - **target = 0; - *str += 1; - return; - case '\\': - if (!parse_backslash(ctx, str)) - continue; - /* fall through */ - default: - addc(target, str); - break; - } - } - uci_parse_error(ctx, *str, "unterminated \""); -} - -/* - * parse a single quoted string argument from the command line - */ -static void parse_single_quote(struct uci_context *ctx, char **str, char **target) -{ - char c; - /* skip quote character */ - *str += 1; - - while ((c = **str)) { - switch(c) { - case '\'': - **target = 0; - *str += 1; - return; - default: - addc(target, str); - } - } - uci_parse_error(ctx, *str, "unterminated '"); -} - -/* - * parse a string from the command line and detect the quoting style - */ -static void parse_str(struct uci_context *ctx, char **str, char **target) -{ - do { - switch(**str) { - case '\'': - parse_single_quote(ctx, str, target); - break; - case '"': - parse_double_quote(ctx, str, target); - break; - case '#': - **str = 0; - /* fall through */ - case 0: - goto done; - case '\\': - if (!parse_backslash(ctx, str)) - continue; - /* fall through */ - default: - addc(target, str); - break; - } - } while (**str && !isspace(**str)); -done: - - /* - * if the string was unquoted and we've stopped at a whitespace - * character, skip to the next one, because the whitespace will - * be overwritten by a null byte here - */ - if (**str) - *str += 1; - - /* terminate the parsed string */ - **target = 0; -} - -/* - * extract the next argument from the command line - */ -static char *next_arg(struct uci_context *ctx, char **str, bool required, bool name) -{ - char *val; - char *ptr; - - val = ptr = *str; - skip_whitespace(ctx, str); - parse_str(ctx, str, &ptr); - if (!*val) { - if (required) - uci_parse_error(ctx, *str, "insufficient arguments"); - goto done; - } - - if (name && !uci_validate_name(val)) - uci_parse_error(ctx, val, "invalid character in field"); - -done: - return val; -} - /* * verify that the end of the line or command is reached. * throw an error if extra arguments are given on the command line @@ -221,7 +62,7 @@ static void assert_eol(struct uci_context *ctx, char **str) char *tmp; tmp = next_arg(ctx, str, false, false); - if (tmp && *tmp && (ctx->flags & UCI_FLAG_STRICT)) + if (*tmp && (ctx->flags & UCI_FLAG_STRICT)) uci_parse_error(ctx, *str, "too many arguments"); } @@ -342,7 +183,9 @@ static void uci_parse_config(struct uci_context *ctx, char **str) /* command string null-terminated by strtok */ *str += strlen(*str) + 1; - type = next_arg(ctx, str, true, true); + type = next_arg(ctx, str, true, false); + if (!uci_validate_str(type, false)) + uci_parse_error(ctx, type, "invalid character in field"); name = next_arg(ctx, str, false, true); assert_eol(ctx, str); @@ -674,10 +517,12 @@ int uci_commit(struct uci_context *ctx, struct uci_package **package, bool overw path = NULL; /* check for updated history, flush */ - uci_load_history(ctx, p, true); + if (!uci_load_history(ctx, p, true)) + goto done; } else { /* flush history */ - uci_load_history(ctx, NULL, true); + if (!uci_load_history(ctx, NULL, true)) + goto done; } }