Partial writes don't cause bytes_transferred underflow

Fixes #2880
This commit is contained in:
Mohammad Nejati
2024-06-06 09:57:07 +00:00
committed by Mohammad Nejati
parent 767397e0c1
commit 74d28c030d
2 changed files with 35 additions and 3 deletions

View File

@ -346,8 +346,8 @@ operator()(
beast::detail::bind_continuation(std::move(*this)));
}
// VFALCO What about consuming the buffer on error?
bytes_transferred_ +=
bytes_transferred - impl.wr_fb.size();
if(bytes_transferred > impl.wr_fb.size())
bytes_transferred_ += bytes_transferred - impl.wr_fb.size();
if(impl.check_stop_now(ec))
goto upcall;
while(remain_ > 0)
@ -431,7 +431,10 @@ operator()(
),
beast::detail::bind_continuation(std::move(*this)));
}
n = bytes_transferred - impl.wr_fb.size();
if(bytes_transferred > impl.wr_fb.size())
n = bytes_transferred - impl.wr_fb.size();
else
n = 0;
bytes_transferred_ += n;
if(impl.check_stop_now(ec))
goto upcall;

View File

@ -806,6 +806,34 @@ public:
BEAST_EXPECT(n1 < n0 + s.size());
}
void
testIssue2880()
{
for(auto fragment : {false, true})
{
net::io_context ioc;
stream<test::stream> wsc{ioc};
stream<test::stream> wss{ioc};
wsc.next_layer().connect(wss.next_layer());
wsc.async_handshake(
"localhost", "/", [](error_code){});
wss.async_accept([](error_code){});
ioc.run();
ioc.restart();
// limit the write size to be less than the header buffer
wsc.next_layer().write_size(3);
if(fragment)
wsc.write_buffer_bytes(8);
wsc.async_write(sbuf("*********"),
[&](error_code ec, std::size_t n)
{
BEAST_EXPECTS(ec, ec.message());
BEAST_EXPECT(n == 0);
});
wsc.next_layer().close();
ioc.run();
}
}
#if BOOST_ASIO_HAS_CO_AWAIT
void testAwaitableCompiles(
@ -835,6 +863,7 @@ public:
testIssue227();
testIssue300();
testIssue1666();
testIssue2880();
#if BOOST_ASIO_HAS_CO_AWAIT
boost::ignore_unused(&write_test::testAwaitableCompiles);
#endif