From 7faaa5deb23049f3b547ecf8260c7c6c9ce70a8f Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Fri, 8 May 2020 21:42:57 +0200 Subject: rewrite parse_range Reject overflows and whitespace. --- hittpd.c | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/hittpd.c b/hittpd.c index a415186..537636c 100644 --- a/hittpd.c +++ b/hittpd.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -130,24 +131,48 @@ on_header_field(http_parser *p, const char *s, size_t l) return 0; } +int scan_int64(const char **s, int64_t *u) { + const char *t = *s; + long x; + for (x=0; *t && (unsigned)(*t)-'0' < 10 && x <= LLONG_MAX/10 - 1; t++) + x = x * 10 + ((*t)-'0'); + if (t != *s) { + *s = t; + *u = x; + return 1; + } + return 0; +} + void parse_range(struct conn_data *data, const char *s, size_t l) { - long n; + if (strncmp("bytes=", s, 6) != 0) + goto invalid; - if (sscanf(s, "bytes=%lu-%lu", &(data->first), &(data->last)) == 2) { - data->last++; // range counts inclusive - return; - } else if (sscanf(s, "bytes=-%lu", &n) == 1 && n > 0) { - data->first = -n; - data->last = -1; - return; - } else if (sscanf(s, "bytes=%lu-", &(data->first)) == 1 && s[l-1] == '-') { + const char *e = s + l; + s += 6; + + if (*s == '-') { + s++; + if (!(scan_int64(&s, &(data->first)) && s == e)) + goto invalid; + data->first = -data->first; data->last = -1; - return; } else { - data->first = data->last = -666; + if (!(scan_int64(&s, &(data->first)) && *s == '-')) + goto invalid; + s++; + if (s == e) + data->last = -1; + else if (!(scan_int64(&s, &(data->last)) && s == e)) + goto invalid; } + + return; + +invalid: + data->first = data->last = -666; } static int -- cgit 1.4.1