From 054475ddbfc080b29d0ffdb1dbcb759f5ed89a8e Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Fri, 22 Oct 2021 14:33:51 +0100 Subject: [PATCH] Fix #1376 - handle comma for unquoted header vars --- mongoose.c | 8 +++++--- src/http.c | 8 +++++--- test/unit_test.c | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/mongoose.c b/mongoose.c index ce300898..45b66c1f 100644 --- a/mongoose.c +++ b/mongoose.c @@ -920,7 +920,7 @@ struct mg_str *mg_http_get_header(struct mg_http_message *h, const char *name) { } static void mg_http_parse_headers(const char *s, const char *end, - struct mg_http_header *h, int max_headers) { + struct mg_http_header *h, int max_headers) { int i; for (i = 0; i < max_headers; i++) { struct mg_str k, v, tmp; @@ -1573,11 +1573,13 @@ static struct mg_str stripquotes(struct mg_str s) { struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) { size_t i; - for (i = 0; i + v.len + 2 < s.len; i++) { + for (i = 0; v.len > 0 && i + v.len + 2 < s.len; i++) { if (s.ptr[i + v.len] == '=' && memcmp(&s.ptr[i], v.ptr, v.len) == 0) { const char *p = &s.ptr[i + v.len + 1], *b = p, *x = &s.ptr[s.len]; int q = p < x && *p == '"' ? 1 : 0; - while (p < x && (q ? p == b || *p != '"' : *p != ';' && *p != ' ')) p++; + while (p < x && + (q ? p == b || *p != '"' : *p != ';' && *p != ' ' && *p != ',')) + p++; // LOG(LL_INFO, ("[%.*s] [%.*s] [%.*s]", (int) s.len, s.ptr, (int) v.len, // v.ptr, (int) (p - b), b)); return stripquotes(mg_str_n(b, (size_t) (p - b + q))); diff --git a/src/http.c b/src/http.c index 54222d08..1e8f8122 100644 --- a/src/http.c +++ b/src/http.c @@ -173,7 +173,7 @@ struct mg_str *mg_http_get_header(struct mg_http_message *h, const char *name) { } static void mg_http_parse_headers(const char *s, const char *end, - struct mg_http_header *h, int max_headers) { + struct mg_http_header *h, int max_headers) { int i; for (i = 0; i < max_headers; i++) { struct mg_str k, v, tmp; @@ -826,11 +826,13 @@ static struct mg_str stripquotes(struct mg_str s) { struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) { size_t i; - for (i = 0; i + v.len + 2 < s.len; i++) { + for (i = 0; v.len > 0 && i + v.len + 2 < s.len; i++) { if (s.ptr[i + v.len] == '=' && memcmp(&s.ptr[i], v.ptr, v.len) == 0) { const char *p = &s.ptr[i + v.len + 1], *b = p, *x = &s.ptr[s.len]; int q = p < x && *p == '"' ? 1 : 0; - while (p < x && (q ? p == b || *p != '"' : *p != ';' && *p != ' ')) p++; + while (p < x && + (q ? p == b || *p != '"' : *p != ';' && *p != ' ' && *p != ',')) + p++; // LOG(LL_INFO, ("[%.*s] [%.*s] [%.*s]", (int) s.len, s.ptr, (int) v.len, // v.ptr, (int) (p - b), b)); return stripquotes(mg_str_n(b, (size_t) (p - b + q))); diff --git a/test/unit_test.c b/test/unit_test.c index 9e5f26d8..da459cc2 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1584,8 +1584,25 @@ static void test_rewrites(void) { ASSERT(mgr.conns == NULL); } +static void test_get_header_var(void) { + struct mg_str empty = mg_str(""), bar = mg_str("bar"), baz = mg_str("baz"); + struct mg_str header = mg_str("Digest foo=\"bar\", blah,boo=baz, x=\"yy\""); + struct mg_str yy = mg_str("yy"); + // struct mg_str x = mg_http_get_header_var(header, mg_str("x")); + // LOG(LL_INFO, ("--> [%d] [%d]", (int) x.len, yy.len)); + ASSERT(mg_strcmp(empty, mg_http_get_header_var(empty, empty)) == 0); + ASSERT(mg_strcmp(empty, mg_http_get_header_var(header, empty)) == 0); + ASSERT(mg_strcmp(empty, mg_http_get_header_var(header, mg_str("fooo"))) == 0); + ASSERT(mg_strcmp(empty, mg_http_get_header_var(header, mg_str("fo"))) == 0); + ASSERT(mg_strcmp(empty, mg_http_get_header_var(header, mg_str("blah"))) == 0); + ASSERT(mg_strcmp(bar, mg_http_get_header_var(header, mg_str("foo"))) == 0); + ASSERT(mg_strcmp(baz, mg_http_get_header_var(header, mg_str("boo"))) == 0); + ASSERT(mg_strcmp(yy, mg_http_get_header_var(header, mg_str("x"))) == 0); +} + int main(void) { mg_log_set("3"); + test_get_header_var(); test_rewrites(); test_check_ip_acl(); test_udp();