case 'p':
if ((word[1] == 0) || !strcmp(word + 1, "ackage"))
uci_parse_package(ctx, &word, single);
+ else
+ goto invalid;
break;
case 'c':
if ((word[1] == 0) || !strcmp(word + 1, "onfig"))
uci_parse_config(ctx, &word);
+ else
+ goto invalid;
break;
case 'o':
if ((word[1] == 0) || !strcmp(word + 1, "ption"))
uci_parse_option(ctx, &word);
+ else
+ goto invalid;
break;
default:
- uci_parse_error(ctx, word, "unterminated command");
- break;
+ goto invalid;
}
+ continue;
+invalid:
+ uci_parse_error(ctx, word, "invalid command");
} while (1);
}
/*
* escape an uci string for export
*/
-static char *uci_escape(struct uci_context *ctx, char *str)
+static char *uci_escape(struct uci_context *ctx, const char *str)
{
- char *s, *p;
- int pos = 0;
+ const char *end;
+ int ofs = 0;
if (!ctx->buf) {
ctx->bufsz = LINEBUF;
ctx->buf = malloc(LINEBUF);
}
- s = str;
- p = strchr(str, '\'');
- if (!p)
- return str;
+ while (1) {
+ int len;
- do {
- int len = p - s;
- if (len > 0) {
- if (p + sizeof(UCI_QUOTE_ESCAPE) - str >= ctx->bufsz) {
- ctx->bufsz *= 2;
- ctx->buf = realloc(ctx->buf, ctx->bufsz);
- if (!ctx->buf)
- UCI_THROW(ctx, UCI_ERR_MEM);
- }
- memcpy(&ctx->buf[pos], s, len);
- pos += len;
+ end = strchr(str, '\'');
+ if (!end)
+ end = str + strlen(str);
+ len = end - str;
+
+ /* make sure that we have enough room in the buffer */
+ while (ofs + len + sizeof(UCI_QUOTE_ESCAPE) + 1 > ctx->bufsz) {
+ ctx->bufsz *= 2;
+ ctx->buf = uci_realloc(ctx, ctx->buf, ctx->bufsz);
}
- strcpy(&ctx->buf[pos], UCI_QUOTE_ESCAPE);
- pos += sizeof(UCI_QUOTE_ESCAPE);
- s = p + 1;
- } while ((p = strchr(s, '\'')));
+ /* copy the string until the character before the quote */
+ memcpy(&ctx->buf[ofs], str, len);
+ ofs += len;
+
+ /* end of string? return the buffer */
+ if (*end == 0)
+ break;
+
+ memcpy(&ctx->buf[ofs], UCI_QUOTE_ESCAPE, sizeof(UCI_QUOTE_ESCAPE));
+ ofs += strlen(&ctx->buf[ofs]);
+ str = end + 1;
+ }
+
+ ctx->buf[ofs] = 0;
return ctx->buf;
}
-
/*
* export a single config package to a file stream
*/
* NB: the config file can still override the package name
*/
if (name) {
- UCI_ASSERT(ctx, uci_validate_name(name));
+ UCI_ASSERT(ctx, uci_validate_str(name, false));
pctx->name = name;
}
{
char *filename;
- UCI_ASSERT(ctx, uci_validate_name(name));
+ UCI_ASSERT(ctx, uci_validate_str(name, false));
filename = uci_malloc(ctx, strlen(name) + strlen(ctx->confdir) + 2);
sprintf(filename, "%s/%s", ctx->confdir, name);
if (!p)
continue;
+ if (!uci_validate_name(p))
+ continue;
+
configs[i] = buf;
strcpy(buf, p);
buf += strlen(buf) + 1;