diff --git a/include/boost/beast/http/detail/basic_parser.ipp b/include/boost/beast/http/detail/basic_parser.ipp index 117fd36a38..d6c53da86a 100644 --- a/include/boost/beast/http/detail/basic_parser.ipp +++ b/include/boost/beast/http/detail/basic_parser.ipp @@ -800,6 +800,16 @@ semi: ec = error::need_more; return; } + if(! detail::is_qpchar(*it)) + { + ec = error::bad_chunk_extension; + return; + } + } + else if(! detail::is_qdchar(*it)) + { + ec = error::bad_chunk_extension; + return; } } ++it; diff --git a/test/beast/http/basic_parser.cpp b/test/beast/http/basic_parser.cpp index 1ee1a45764..3539fab7a6 100644 --- a/test/beast/http/basic_parser.cpp +++ b/test/beast/http/basic_parser.cpp @@ -1678,6 +1678,40 @@ class basic_parser_test : public beast::unit_test::suite } } + void + testChunkExtensions() + { + // a quoted chunk-ext value is a quoted-string and may only hold + // qdtext or a valid quoted-pair, see rfc7230 section 4.1.1 + auto const ce = + [&](string_view chunk, error_code expected) + { + string_view const hdr = + "POST / HTTP/1.1\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n"; + test_parser p; + p.eager(true); + error_code ec; + p.put(net::buffer(hdr.data(), hdr.size()), ec); + BEAST_EXPECT(p.is_header_done()); + p.put(net::buffer(chunk.data(), chunk.size()), ec); + BEAST_EXPECTS(ec == expected, ec.message()); + }; + // valid + ce("1;a=\"xy\"\r\nX\r\n0\r\n\r\n", {}); + ce("1;a=\"\\\"\"\r\nX\r\n0\r\n\r\n", {}); + // a bare LF inside the quotes is not qdtext + ce("1;a=\"\n\"\r\nX\r\n0\r\n\r\n", + error::bad_chunk_extension); + // a control character inside the quotes is not qdtext + ce("1;a=\"\x01\"\r\nX\r\n0\r\n\r\n", + error::bad_chunk_extension); + // a quoted-pair must escape a qpchar, not a control character + ce("1;a=\"\\\n\"\r\nX\r\n0\r\n\r\n", + error::bad_chunk_extension); + } + void testUnlimitedBody() { @@ -1740,6 +1774,7 @@ class basic_parser_test : public beast::unit_test::suite testIssue1267(); testChunkedOverflow(); testChunkedBodySize(); + testChunkExtensions(); testUnlimitedBody(); testIssue2201(); }