From e84c698fefb4d1f69ce687736811cf9474437195 Mon Sep 17 00:00:00 2001 From: omjego Date: Tue, 25 Aug 2020 08:16:07 +0000 Subject: [PATCH 1/2] 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. --- httplib.h | 10 ++++++++-- test/test.cc | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/httplib.h b/httplib.h index 7e9f2a53af..cc9612177e 100644 --- a/httplib.h +++ b/httplib.h @@ -1454,8 +1454,11 @@ inline std::pair trim(const char *b, const char *e, int left, template void split(const char *b, const char *e, char d, Fn fn) { int i = 0; int beg = 0; + if(!b) { + return; + } - 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]); @@ -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 c04bb0c90a..6bb7fbb155 100644 --- a/test/test.cc +++ b/test/test.cc @@ -66,6 +66,13 @@ TEST(SplitTest, ParseQueryString) { EXPECT_EQ("val3", dic.find("key3")->second); } +TEST(SplitTest, ParseQueryWithSingleSpaceChar) { + 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; From f1807bb789fcad4f5b61fb32f3e252ab30a68993 Mon Sep 17 00:00:00 2001 From: omjego Date: Thu, 27 Aug 2020 13:53:12 +0000 Subject: [PATCH 2/2] Fix parsing to parse query string with single space char. --- httplib.h | 12 ++++++------ test/test.cc | 21 ++++++++++++++++----- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/httplib.h b/httplib.h index cc9612177e..18616c758f 100644 --- a/httplib.h +++ b/httplib.h @@ -1454,14 +1454,13 @@ inline std::pair trim(const char *b, const char *e, int left, template void split(const char *b, const char *e, char d, Fn fn) { int i = 0; int beg = 0; - if(!b) { - return; - } 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++; @@ -1469,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]); + } } } @@ -2835,7 +2836,6 @@ inline std::string params_to_query_str(const Params ¶ms) { query += "="; query += encode_url(it->second); } - return query; } diff --git a/test/test.cc b/test/test.cc index 6bb7fbb155..29f60ca398 100644 --- a/test/test.cc +++ b/test/test.cc @@ -66,13 +66,24 @@ TEST(SplitTest, ParseQueryString) { EXPECT_EQ("val3", dic.find("key3")->second); } -TEST(SplitTest, ParseQueryWithSingleSpaceChar) { - string s = " "; - Params dict; - detail::parse_query_text(s, dict); - EXPECT_TRUE(dict.empty()); +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;