mirror of
https://codeberg.org/dnkl/yambar.git
synced 2025-04-24 21:05:40 +02:00
module/script: improved verification of tag type parameters and tag values
* Verify int/float/bool values are that, and nothing else * Verify tag ranges are integers * Verify a range tag value is inside its range * Don’t allow anything but false|true for booleans
This commit is contained in:
parent
d10ad8924b
commit
74754b0ab9
1 changed files with 67 additions and 22 deletions
|
@ -67,16 +67,6 @@ content(struct module *mod)
|
|||
return e;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
str_to_bool(const char *s)
|
||||
{
|
||||
return strcasecmp(s, "on") == 0 ||
|
||||
strcasecmp(s, "true") == 0 ||
|
||||
strcasecmp(s, "yes") == 0 ||
|
||||
strtoul(s, NULL, 0) > 0;
|
||||
}
|
||||
|
||||
static struct tag *
|
||||
process_line(struct module *mod, const char *line, size_t len)
|
||||
{
|
||||
|
@ -118,14 +108,43 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
if (type_len == 6 && memcmp(type, "string", 6) == 0)
|
||||
tag = tag_new_string(mod, name, value);
|
||||
|
||||
else if (type_len == 3 && memcmp(type, "int", 3) == 0)
|
||||
tag = tag_new_int(mod, name, strtol(value, NULL, 0));
|
||||
else if (type_len == 3 && memcmp(type, "int", 3) == 0) {
|
||||
errno = 0;
|
||||
char *end;
|
||||
long v = strtol(value, &end, 0);
|
||||
|
||||
else if (type_len == 4 && memcmp(type, "bool", 4) == 0)
|
||||
tag = tag_new_bool(mod, name, str_to_bool(value));
|
||||
if (errno != 0 || *end != '\0') {
|
||||
LOG_ERR("tag value is not an integer: %s", value);
|
||||
goto bad_tag;
|
||||
}
|
||||
tag = tag_new_int(mod, name, v);
|
||||
}
|
||||
|
||||
else if (type_len == 5 && memcmp(type, "float", 5) == 0)
|
||||
tag = tag_new_float(mod, name, strtod(value, NULL));
|
||||
else if (type_len == 4 && memcmp(type, "bool", 4) == 0) {
|
||||
bool v;
|
||||
if (strcmp(value, "true") == 0)
|
||||
v = true;
|
||||
else if (strcmp(value, "false") == 0)
|
||||
v = false;
|
||||
else {
|
||||
LOG_ERR("tag value is not a boolean: %s", value);
|
||||
goto bad_tag;
|
||||
}
|
||||
tag = tag_new_bool(mod, name, v);
|
||||
}
|
||||
|
||||
else if (type_len == 5 && memcmp(type, "float", 5) == 0) {
|
||||
errno = 0;
|
||||
char *end;
|
||||
double v = strtod(value, &end);
|
||||
|
||||
if (errno != 0 || *end != '\0') {
|
||||
LOG_ERR("tag value is not a float: %s", value);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
tag = tag_new_float(mod, name, v);
|
||||
}
|
||||
|
||||
else if ((type_len > 6 && memcmp(type, "range:", 6) == 0) ||
|
||||
(type_len > 9 && memcmp(type, "realtime:", 9 == 0)))
|
||||
|
@ -133,8 +152,12 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
const char *_start = type + 6;
|
||||
const char *split = memchr(_start, '-', type_len - 6);
|
||||
|
||||
if (split == NULL || split == _start || (split + 1) - type >= type_len)
|
||||
if (split == NULL || split == _start || (split + 1) - type >= type_len) {
|
||||
LOG_ERR(
|
||||
"tag range delimiter ('-') not found in type: %.*s",
|
||||
(int)type_len, type);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
const char *_end = split + 1;
|
||||
|
||||
|
@ -143,8 +166,12 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
|
||||
long start = 0;
|
||||
for (size_t i = 0; i < start_len; i++) {
|
||||
if (!(_start[i] >= '0' && _start[i] <= '9'))
|
||||
if (!(_start[i] >= '0' && _start[i] <= '9')) {
|
||||
LOG_ERR(
|
||||
"tag range start is not an integer: %.*s",
|
||||
(int)start_len, _start);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
start *= 10;
|
||||
start += _start[i] - '0';
|
||||
|
@ -152,19 +179,37 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
|
||||
long end = 0;
|
||||
for (size_t i = 0; i < end_len; i++) {
|
||||
if (!(_end[i] >= '0' && _end[i] < '9'))
|
||||
if (!(_end[i] >= '0' && _end[i] < '9')) {
|
||||
LOG_ERR(
|
||||
"tag range end is not an integer: %.*s",
|
||||
(int)end_len, _end);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
end *= 10;
|
||||
end += _end[i] - '0';
|
||||
}
|
||||
|
||||
if (type_len > 9 && memcmp(type, "realtime:", 9) == 0) {
|
||||
LOG_WARN("unimplemented: realtime tag");
|
||||
LOG_ERR("unimplemented: realtime tag");
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
tag = tag_new_int_range(mod, name, strtol(value, NULL, 0), start, end);
|
||||
errno = 0;
|
||||
char *vend;
|
||||
long v = strtol(value, &vend, 0);
|
||||
if (errno != 0 || *vend != '\0') {
|
||||
LOG_ERR("tag value is not an integer: %s", value);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
if (v < start || v > end) {
|
||||
LOG_ERR("tag value is outside range: %ld <= %ld <= %ld",
|
||||
start, v, end);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
tag = tag_new_int_range(mod, name, v, start, end);
|
||||
}
|
||||
|
||||
else {
|
||||
|
@ -176,7 +221,7 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
return tag;
|
||||
|
||||
bad_tag:
|
||||
LOG_ERR("invalid: %.*s", (int)len, line);
|
||||
LOG_ERR("invalid tag: %.*s", (int)len, line);
|
||||
free(name);
|
||||
free(value);
|
||||
return NULL;
|
||||
|
|
Loading…
Add table
Reference in a new issue