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
2026-09-27 19:20:14 -04:00
committed by GitHub
parent 2fb2dbbe1e
commit 57c4f7f385
2 changed files with 16 additions and 1 deletions
+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;
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
View File
@@ -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;