Quellcode durchsuchen

Reject trailing characters in HTTP quality values (#2590)

parse_quality accepted values such as q=0.5junk because it checked only the conversion error and ignored the returned end pointer. Require the numeric parser to consume the complete q parameter so malformed Accept values are rejected and invalid Accept-Encoding weights are ignored. Add regression cases for both headers.
DosX vor 1 Woche
Ursprung
Commit
57c4f7f385
2 geänderte Dateien mit 16 neuen und 1 gelöschten Zeilen
  1. 2 1
      httplib.h
  2. 14 0
      test/test.cc

+ 2 - 1
httplib.h

@@ -7623,7 +7623,8 @@ inline bool parse_quality(const char *b, const char *e, std::string &token,
 
                double v = 0.0;
                auto res = from_chars(pb + r.first, pb + r.second, v);
-               if (res.ec != std::errc{} || v < 0.0 || v > 1.0) {
+               if (res.ec != std::errc{} || res.ptr != pb + r.second ||
+                   v < 0.0 || v > 1.0) {
                  invalid = true;
                  return true;
                }

+ 14 - 0
test/test.cc

@@ -1059,6 +1059,10 @@ TEST(ParseAcceptHeaderTest, InvalidCases) {
   EXPECT_FALSE(detail::parse_accept_header(
       "text/html;q=invalid,application/json", result));
 
+  // A valid numeric prefix does not make the entire quality value valid.
+  EXPECT_FALSE(detail::parse_accept_header(
+      "text/html;q=0.5junk,application/json", result));
+
   // Empty quality value
   EXPECT_FALSE(
       detail::parse_accept_header("text/html;q=,application/json", result));
@@ -2112,6 +2116,16 @@ TEST(ParseAcceptEncoding5, AcceptEncodingQZeroVariants) {
   EXPECT_TRUE(ret == detail::EncodingType::None);
 }
 
+TEST(ParseAcceptEncodingTest, RejectsTrailingQualityCharacters) {
+  Request req;
+  req.set_header("Accept-Encoding", "gzip;q=0.5junk");
+
+  Response res;
+  res.set_header("Content-Type", "text/plain");
+
+  EXPECT_EQ(detail::EncodingType::None, detail::encoding_type(req, res));
+}
+
 TEST(ParseAcceptEncoding6, AcceptEncodingXGzipQZero) {
   // x-gzip;q=0 should not cause "gzip" to be incorrectly detected
   Request req;