mirror of
https://github.com/boostorg/beast.git
synced 2025-08-03 06:44:39 +02:00
Fix leftovers in basic_parser corner case:
fix #1734, close #1736 buf_.get() has size `buf_len_`, but only `size` number of octets in that buffer is valid.
This commit is contained in:
committed by
Vinnie Falco
parent
cee64b5223
commit
1abe92f524
@@ -1,3 +1,9 @@
|
||||
Version 274:
|
||||
|
||||
* Fix leftovers in basic_parser corner case
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Version 273:
|
||||
|
||||
* Squelch spurious websocket timer assert
|
||||
|
@@ -128,6 +128,8 @@ class basic_parser
|
||||
template<bool OtherIsRequest>
|
||||
friend class basic_parser;
|
||||
|
||||
friend class basic_parser_test;
|
||||
|
||||
protected:
|
||||
/// Default constructor
|
||||
basic_parser() = default;
|
||||
|
@@ -51,9 +51,9 @@ put(ConstBufferSequence const& buffers,
|
||||
}
|
||||
// flatten
|
||||
net::buffer_copy(net::buffer(
|
||||
buf_.get(), buf_len_), buffers);
|
||||
buf_.get(), size), buffers);
|
||||
return put(net::const_buffer{
|
||||
buf_.get(), buf_len_}, ec);
|
||||
buf_.get(), size}, ec);
|
||||
}
|
||||
|
||||
template<bool isRequest>
|
||||
|
@@ -1286,6 +1286,98 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// https://github.com/boostorg/beast/issues/1734
|
||||
|
||||
void
|
||||
testIssue1734()
|
||||
{
|
||||
// Ensure more than one buffer, this is to avoid an optimized path in
|
||||
// basic_parser::put(ConstBufferSequence const&,...) which avoids
|
||||
// buffer flattening.
|
||||
auto multibufs = [](multi_buffer::const_buffers_type buffers) {
|
||||
std::vector<net::const_buffer> bs;
|
||||
for (auto b : buffers_range(buffers))
|
||||
bs.push_back(b);
|
||||
while (std::distance(bs.begin(), bs.end()) < 2) {
|
||||
bs.push_back({});
|
||||
}
|
||||
return bs;
|
||||
};
|
||||
|
||||
// Buffers must be bigger than max_stack_buffer to force flattening
|
||||
// in basic_parser::put(ConstBufferSequence const&,...)
|
||||
std::string first_chunk_data(
|
||||
2 * basic_parser<false>::max_stack_buffer + 1, 'x');
|
||||
|
||||
std::string second_chunk_data_part1(
|
||||
basic_parser<false>::max_stack_buffer + 2, 'x');
|
||||
std::string second_chunk_data_part2(
|
||||
basic_parser<false>::max_stack_buffer + 1, 'x');
|
||||
|
||||
multi_buffer b;
|
||||
parser<false, string_body> p;
|
||||
p.eager(true);
|
||||
error_code ec;
|
||||
std::size_t used;
|
||||
|
||||
ostream(b) <<
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Server: test\r\n"
|
||||
"Transfer-Encoding: chunked\r\n"
|
||||
"\r\n";
|
||||
|
||||
used = p.put(b.data(), ec);
|
||||
b.consume(used);
|
||||
|
||||
BEAST_EXPECT(net::buffer_size(b.data()) == 0);
|
||||
BEAST_EXPECTS(!ec, ec.message());
|
||||
BEAST_EXPECT(!p.is_done());
|
||||
BEAST_EXPECT(p.is_header_done());
|
||||
|
||||
ostream(b) <<
|
||||
std::hex <<
|
||||
first_chunk_data.size() << "\r\n" <<
|
||||
first_chunk_data << "\r\n";
|
||||
|
||||
// First chunk
|
||||
used = p.put(multibufs(b.data()), ec);
|
||||
b.consume(used);
|
||||
|
||||
BEAST_EXPECTS(ec == error::need_more, ec.message());
|
||||
BEAST_EXPECT(!p.is_done());
|
||||
|
||||
ostream(b) <<
|
||||
std::hex <<
|
||||
(second_chunk_data_part1.size() +
|
||||
second_chunk_data_part2.size() ) << "\r\n" <<
|
||||
second_chunk_data_part1;
|
||||
|
||||
// Second chunk, part 1
|
||||
used = p.put(multibufs(b.data()), ec);
|
||||
b.consume(used);
|
||||
|
||||
BEAST_EXPECTS(!ec, ec.message());
|
||||
BEAST_EXPECT(!p.is_done());
|
||||
|
||||
ostream(b) <<
|
||||
second_chunk_data_part2 << "\r\n"
|
||||
<< "0\r\n\r\n";
|
||||
|
||||
// Second chunk, part 2
|
||||
used = p.put(multibufs(b.data()), ec);
|
||||
b.consume(used);
|
||||
|
||||
BEAST_EXPECTS(!ec, ec.message()); // <-- Error: bad chunk
|
||||
if(p.need_eof())
|
||||
{
|
||||
p.put_eof(ec);
|
||||
BEAST_EXPECTS(! ec, ec.message());
|
||||
}
|
||||
BEAST_EXPECT(p.is_done());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
|
Reference in New Issue
Block a user