Browse Source

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.
Omkar Jadhav 5 years ago
parent
commit
b0fd4befb1
2 changed files with 29 additions and 5 deletions
  1. 11 5
      httplib.h
  2. 18 0
      test/test.cc

+ 11 - 5
httplib.h

@@ -1455,10 +1455,12 @@ template <class Fn> 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 <class Fn> 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 &params) {
     query += "=";
     query += encode_url(it->second);
   }
-
   return query;
 }
 
@@ -2847,7 +2850,10 @@ inline void parse_query_text(const std::string &s, Params &params) {
         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));
+    }
   });
 }
 

+ 18 - 0
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;