/* 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);
goto error;
if (option && !uci_validate_name(option))
goto error;
- if ((rename || (!option && !delete)) && !uci_validate_name(value))
+ if (rename && !uci_validate_str(value, (option || delete)))
goto error;
if (rename)
list = e->list.prev;
switch(e->type) {
case UCI_TYPE_SECTION:
- UCI_ASSERT(ctx, uci_validate_name(value));
+ UCI_ASSERT(ctx, uci_validate_str(value, false));
size = sizeof(struct uci_section);
s = uci_to_section(e);
section = e->name;
UCI_ASSERT(ctx, uci_validate_name(option));
UCI_ASSERT(ctx, value != NULL);
} else {
- UCI_ASSERT(ctx, uci_validate_name(value));
+ UCI_ASSERT(ctx, uci_validate_str(value, false));
}
/*
return ptr;
}
-static bool uci_validate_name(const char *str)
+/*
+ * validate strings for names and types, reject special characters
+ * for names, only alphanum and _ is allowed (shell compatibility)
+ * for types, we allow more characters
+ */
+static bool uci_validate_str(const char *str, bool name)
{
if (!*str)
return false;
while (*str) {
- if (!isalnum(*str) && (*str != '_'))
- return false;
+ char c = *str;
+ if (!isalnum(c) && c != '_') {
+ if (name || (c < 33) || (c > 126))
+ return false;
+ }
str++;
}
return true;
}
+static inline bool uci_validate_name(const char *str)
+{
+ return uci_validate_str(str, true);
+}
+
static void uci_alloc_parse_context(struct uci_context *ctx)
{
ctx->pctx = (struct uci_parse_context *) uci_malloc(ctx, sizeof(struct uci_parse_context));