mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
committed by
Mohammad Nejati
parent
4bff457ef7
commit
767397e0c1
@ -311,8 +311,9 @@ struct impl_base<true>
|
||||
read_size_hint_pmd(
|
||||
std::size_t initial_size,
|
||||
bool rd_done,
|
||||
std::uint64_t rd_msg_max,
|
||||
std::uint64_t rd_remain,
|
||||
detail::frame_header const& rd_fh) const
|
||||
frame_header const& rd_fh) const
|
||||
{
|
||||
using beast::detail::clamp;
|
||||
std::size_t result;
|
||||
@ -339,6 +340,9 @@ struct impl_base<true>
|
||||
initial_size, clamp(rd_remain));
|
||||
done:
|
||||
BOOST_ASSERT(result != 0);
|
||||
// Ensure offered size does not exceed rd_msg_max
|
||||
if(rd_msg_max)
|
||||
result = clamp(result, rd_msg_max);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
@ -461,6 +465,7 @@ struct impl_base<false>
|
||||
read_size_hint_pmd(
|
||||
std::size_t initial_size,
|
||||
bool rd_done,
|
||||
std::uint64_t rd_msg_max,
|
||||
std::uint64_t rd_remain,
|
||||
frame_header const& rd_fh) const
|
||||
{
|
||||
@ -485,6 +490,9 @@ struct impl_base<false>
|
||||
initial_size, clamp(rd_remain));
|
||||
}
|
||||
BOOST_ASSERT(result != 0);
|
||||
// Ensure offered size does not exceed rd_msg_max
|
||||
if(rd_msg_max)
|
||||
result = clamp(result, rd_msg_max);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
@ -986,7 +986,7 @@ read_some(
|
||||
if(! limit)
|
||||
limit = (std::numeric_limits<std::size_t>::max)();
|
||||
auto const size =
|
||||
clamp(read_size_hint(buffer), limit);
|
||||
clamp(impl_->read_size_hint_db(buffer), limit);
|
||||
BOOST_ASSERT(size > 0);
|
||||
auto mb = beast::detail::dynamic_buffer_prepare(
|
||||
buffer, size, ec, error::buffer_overflow);
|
||||
|
@ -133,7 +133,7 @@ read_size_hint(
|
||||
std::size_t initial_size) const
|
||||
{
|
||||
return impl_->read_size_hint_pmd(
|
||||
initial_size, impl_->rd_done,
|
||||
initial_size, impl_->rd_done, impl_->rd_msg_max,
|
||||
impl_->rd_remain, impl_->rd_fh);
|
||||
}
|
||||
|
||||
|
@ -300,7 +300,7 @@ struct stream<NextLayer, deflateSupported>::impl_type
|
||||
if(initial_size == 0)
|
||||
return 1; // buffer is full
|
||||
return this->read_size_hint_pmd(
|
||||
initial_size, rd_done, rd_remain, rd_fh);
|
||||
initial_size, rd_done, rd_msg_max, rd_remain, rd_fh);
|
||||
}
|
||||
|
||||
template<class DynamicBuffer>
|
||||
@ -886,6 +886,9 @@ parse_fh(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// The final size of a deflated frame is unknown. In certain cases,
|
||||
// post-inflation, it might shrink and become <= rd_msg_max.
|
||||
// Therefore, we will verify the size during the inflation process.
|
||||
if(! this->rd_deflated())
|
||||
{
|
||||
if(rd_msg_max && beast::detail::sum_exceeds(
|
||||
|
@ -993,6 +993,127 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests when a deflate frame doesn't prepare the supplied buffer
|
||||
* more than rd_msg_max.
|
||||
*/
|
||||
void
|
||||
testIssue2879()
|
||||
{
|
||||
// contains a deflate block with a size of 288230380446614262 (truncated at the end)
|
||||
auto frame = sbuf(
|
||||
"\xc2\xff\x04\x00\x00\x00\xff\xff\x02\xf6"
|
||||
"\x4c\x31\x0d\x0a\x66\x3a\x27\x00\x00\x69"
|
||||
"\x20\x20\x20\xff\x46\x00\x00\x10\x00\x6f"
|
||||
"\x29\x00\xd6\x2e\x31\x0d\x0a\x48\x6f\x73"
|
||||
"\x74\x3a\x42\x42\x42\x52\x41\x41\x45\x42"
|
||||
"\x42\x42\x42\x42\x42\x01\x01\x01\x01\x01"
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
|
||||
"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff"
|
||||
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x01\x01\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
|
||||
"\x0f\x0f\x0f\x0f\x0f\x0f\x01\x01\x01\x01"
|
||||
"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
|
||||
"\x01\x43\x43\x43\x43\x43\x3f\x3f\x28\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x45\x54\x50\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
|
||||
"\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x43\x43\x43"
|
||||
"\x43\x43\x43\x43\x43\x43\x43\x70\x67\x72"
|
||||
"\x61\x64\x65\x00\x54\x00");
|
||||
|
||||
permessage_deflate pmd;
|
||||
pmd.client_enable = true;
|
||||
pmd.server_enable = true;
|
||||
|
||||
// read
|
||||
{
|
||||
net::io_context ioc;
|
||||
stream<test::stream> wsc{ioc};
|
||||
stream<test::stream> wss{ioc};
|
||||
wsc.set_option(pmd);
|
||||
wss.set_option(pmd);
|
||||
wss.read_message_max(2048);
|
||||
wsc.next_layer().connect(wss.next_layer());
|
||||
wsc.async_handshake(
|
||||
"localhost", "/", [](error_code){});
|
||||
wss.async_accept([](error_code){});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(wsc.is_open());
|
||||
BEAST_EXPECT(wss.is_open());
|
||||
net::write(wsc.next_layer(), frame);
|
||||
error_code ec;
|
||||
flat_buffer b;
|
||||
wss.read(b, ec);
|
||||
BEAST_EXPECTS(ec == error::message_too_big, ec.message());
|
||||
}
|
||||
|
||||
// async read
|
||||
{
|
||||
net::io_context ioc;
|
||||
stream<test::stream> wsc{ioc};
|
||||
stream<test::stream> wss{ioc};
|
||||
wsc.set_option(pmd);
|
||||
wss.set_option(pmd);
|
||||
wss.read_message_max(2048);
|
||||
wsc.next_layer().connect(wss.next_layer());
|
||||
wsc.async_handshake(
|
||||
"localhost", "/", [](error_code){});
|
||||
wss.async_accept([](error_code){});
|
||||
ioc.run();
|
||||
ioc.restart();
|
||||
BEAST_EXPECT(wsc.is_open());
|
||||
BEAST_EXPECT(wss.is_open());
|
||||
net::write(wsc.next_layer(), frame);
|
||||
error_code ec;
|
||||
flat_buffer b;
|
||||
wss.async_read(b,
|
||||
[&ec](error_code ec_, std::size_t){ ec = ec_; });
|
||||
ioc.run();
|
||||
BEAST_EXPECTS(ec == error::message_too_big, ec.message());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testMoveOnly()
|
||||
{
|
||||
@ -1038,6 +1159,7 @@ public:
|
||||
testIssue807();
|
||||
testIssue954();
|
||||
testIssue1630();
|
||||
testIssue2879();
|
||||
testIssueBF1();
|
||||
testIssueBF2();
|
||||
testMoveOnly();
|
||||
|
Reference in New Issue
Block a user