Browse Source

Fix crash caused by header field regex complexity (#457)

Matthew DeVore 5 years ago
parent
commit
ed1b6afa10
2 changed files with 14 additions and 1 deletions
  1. 1 1
      httplib.h
  2. 13 0
      test/test.cc

+ 1 - 1
httplib.h

@@ -1847,7 +1847,7 @@ inline bool read_headers(Stream &strm, Headers &headers) {
     // the left or right side of the header value:
     //  - https://stackoverflow.com/questions/50179659/
     //  - https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
-    static const std::regex re(R"(([^:]+):[\t ]*(.+))");
+    static const std::regex re(R"(([^:]+):[\t ]*([^\t ].*))");
 
     std::cmatch m;
     if (std::regex_match(line_reader.ptr(), end, m, re)) {

+ 13 - 0
test/test.cc

@@ -2333,6 +2333,19 @@ TEST(ServerRequestParsingTest, ReadHeadersRegexComplexity2) {
       "&&&%%%");
 }
 
+TEST(ServerRequestParsingTest, ExcessiveWhitespaceInUnparseableHeaderLine) {
+  // Make sure this doesn't crash the server.
+  // In a previous version of the header line regex, the "\r" rendered the line
+  // unparseable and the regex engine repeatedly backtracked, trying to look for
+  // a new position where the leading white space ended and the field value
+  // began.
+  // The crash occurs with libc++ but not libstdc++.
+  test_raw_request("GET /hi HTTP/1.1\r\n"
+                   "a:" + std::string(2000, ' ') + '\r' + std::string(20, 'z') +
+                   "\r\n"
+                   "\r\n");
+}
+
 TEST(ServerRequestParsingTest, InvalidFirstChunkLengthInRequest) {
   std::string out;