From b0fd4befb11d8f02af777f23b2562cf6078a28c4 Mon Sep 17 00:00:00 2001 From: Omkar Jadhav Date: Fri, 28 Aug 2020 19:13:28 +0530 Subject: [PATCH] Fix query parsing issues (#629) * Fix parsing to parse query string with single space char. When passed ' ' as a query string, the server crashes cause of illegal memory access done in httplib::detail::split. Have added checks to make sure the split function has a valid string with length > 0. * Fix parsing to parse query string with single space char. --- httplib.h | 16 +++++++++++----- test/test.cc | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/httplib.h b/httplib.h index 9cdf18d..2a3fd40 100644 --- a/httplib.h +++ b/httplib.h @@ -1455,10 +1455,12 @@ template void split(const char *b, const char *e, char d, Fn fn) { int i = 0; int beg = 0; - while (e ? (b + i != e) : (b[i] != '\0')) { + while (e ? (b + i < e) : (b[i] != '\0')) { if (b[i] == d) { auto r = trim(b, e, beg, i); - fn(&b[r.first], &b[r.second]); + if (r.first < r.second) { + fn(&b[r.first], &b[r.second]); + } beg = i + 1; } i++; @@ -1466,7 +1468,9 @@ template void split(const char *b, const char *e, char d, Fn fn) { if (i) { auto r = trim(b, e, beg, i); - fn(&b[r.first], &b[r.second]); + if (r.first < r.second) { + fn(&b[r.first], &b[r.second]); + } } } @@ -2832,7 +2836,6 @@ inline std::string params_to_query_str(const Params ¶ms) { query += "="; query += encode_url(it->second); } - return query; } @@ -2847,7 +2850,10 @@ inline void parse_query_text(const std::string &s, Params ¶ms) { val.assign(b2, e2); } }); - params.emplace(decode_url(key, true), decode_url(val, true)); + + if(!key.empty()) { + params.emplace(decode_url(key, true), decode_url(val, true)); + } }); } diff --git a/test/test.cc b/test/test.cc index c04bb0c..29f60ca 100644 --- a/test/test.cc +++ b/test/test.cc @@ -66,6 +66,24 @@ TEST(SplitTest, ParseQueryString) { EXPECT_EQ("val3", dic.find("key3")->second); } +TEST(SplitTest, ParseInvalidQueryTests) { + + { + string s = " "; + Params dict; + detail::parse_query_text(s, dict); + EXPECT_TRUE(dict.empty()); + } + + { + string s = " = ="; + Params dict; + detail::parse_query_text(s, dict); + EXPECT_TRUE(dict.empty()); + } +} + + TEST(ParseQueryTest, ParseQueryString) { string s = "key1=val1&key2=val2&key3=val3"; Params dic;