aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2020-10-11 22:00:25 +0200
committerPřemysl Eric Janouch <p@janouch.name>2020-10-12 02:07:14 +0200
commit7e5b6c534399d2c56412383ef66658bd361d5027 (patch)
tree928c66c6e743ab8a7dc625d29f87aaff9fe04941
parentc2c5031538e9d48925c758b23df8d093358ba3fd (diff)
downloadliberty-7e5b6c534399d2c56412383ef66658bd361d5027.tar.gz
liberty-7e5b6c534399d2c56412383ef66658bd361d5027.tar.xz
liberty-7e5b6c534399d2c56412383ef66658bd361d5027.zip
Fix crashes in the config parser
It had a duality between not requiring null-terminated input and relying on it, depending on where you looked.
-rw-r--r--liberty.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/liberty.c b/liberty.c
index c5da820..6c9cee3 100644
--- a/liberty.c
+++ b/liberty.c
@@ -5087,18 +5087,21 @@ config_tokenizer_next (struct config_tokenizer *self, struct error **e)
return CONFIG_T_STRING;
}
- char *end;
+ // Our input doesn't need to be NUL-terminated but we want to use strtoll()
+ char buf[48] = "", *end = buf;
+ size_t buf_len = MIN (sizeof buf - 1, self->len);
+
errno = 0;
- self->integer = strtoll (self->p, &end, 10);
+ self->integer = strtoll (strncpy (buf, self->p, buf_len), &end, 10);
if (errno == ERANGE)
{
config_tokenizer_error (self, e, "integer out of range");
return CONFIG_T_ABORT;
}
- if (end != self->p)
+ if (end != buf)
{
- self->len -= end - self->p;
- self->p = end;
+ self->len -= end - buf;
+ self->p += end - buf;
return CONFIG_T_INTEGER;
}
@@ -5111,7 +5114,7 @@ config_tokenizer_next (struct config_tokenizer *self, struct error **e)
str_reset (&self->string);
do
str_append_c (&self->string, config_tokenizer_advance (self));
- while (config_tokenizer_is_word_char (*self->p));
+ while (self->len && config_tokenizer_is_word_char (*self->p));
if (!strcmp (self->string.str, "null"))
return CONFIG_T_NULL;