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.
This commit is contained in:
DosX authored and GitHub committed 2026-09-27 19:20:14 -04:00
1 parent 2fb2dbbe1e
commit 57c4f7f385
2 files changed
+16 -1

No files matched your search

+2 -1
View File
@@ -7623,7 +7623,8 @@ inline bool parse_quality(const char *b, const char *e, std::string &token,
double v = 0.0; double v = 0.0;
auto res = from_chars(pb + r.first, pb + r.second, v); 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; invalid = true;
return true; return true;
} }
+14
View File
@@ -1059,6 +1059,10 @@ TEST(ParseAcceptHeaderTest, InvalidCases) {
EXPECT_FALSE(detail::parse_accept_header( EXPECT_FALSE(detail::parse_accept_header(
"text/html;q=invalid,application/json", result)); "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 // Empty quality value
EXPECT_FALSE( EXPECT_FALSE(
detail::parse_accept_header("text/html;q=,application/json", result)); detail::parse_accept_header("text/html;q=,application/json", result));
@@ -2112,6 +2116,16 @@ TEST(ParseAcceptEncoding5, AcceptEncodingQZeroVariants) {
EXPECT_TRUE(ret == detail::EncodingType::None); 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) { TEST(ParseAcceptEncoding6, AcceptEncodingXGzipQZero) {
// x-gzip;q=0 should not cause "gzip" to be incorrectly detected // x-gzip;q=0 should not cause "gzip" to be incorrectly detected
Request req; Request req;