mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 12:57:31 +02:00
Fix flat_streambuf:
Don't call memcpy or memmove with null arguments.
This commit is contained in:
@ -3,6 +3,7 @@
|
|||||||
* CMake hide command lines in .vcxproj Output windows"
|
* CMake hide command lines in .vcxproj Output windows"
|
||||||
* Rename to detail::is_invocable
|
* Rename to detail::is_invocable
|
||||||
* Rename project to http-bench
|
* Rename project to http-bench
|
||||||
|
* Fix flat_streambuf
|
||||||
|
|
||||||
WebSocket:
|
WebSocket:
|
||||||
|
|
||||||
|
@ -193,12 +193,15 @@ prepare(std::size_t n) ->
|
|||||||
{
|
{
|
||||||
if(n <= dist(out_, end_))
|
if(n <= dist(out_, end_))
|
||||||
{
|
{
|
||||||
|
// existing capacity is sufficient
|
||||||
last_ = out_ + n;
|
last_ = out_ + n;
|
||||||
return{out_, n};
|
return{out_, n};
|
||||||
}
|
}
|
||||||
auto const len = size();
|
auto const len = size();
|
||||||
if(n <= dist(p_, end_) - len)
|
if(n <= capacity() - len)
|
||||||
{
|
{
|
||||||
|
// after a memmove,
|
||||||
|
// existing capacity is sufficient
|
||||||
if(len > 0)
|
if(len > 0)
|
||||||
std::memmove(p_, in_, len);
|
std::memmove(p_, in_, len);
|
||||||
in_ = p_;
|
in_ = p_;
|
||||||
@ -206,17 +209,24 @@ prepare(std::size_t n) ->
|
|||||||
last_ = out_ + n;
|
last_ = out_ + n;
|
||||||
return {out_, n};
|
return {out_, n};
|
||||||
}
|
}
|
||||||
|
// enforce maximum capacity
|
||||||
if(n > max_ - len)
|
if(n > max_ - len)
|
||||||
throw std::length_error{
|
throw std::length_error{
|
||||||
"flat_streambuf overflow"};
|
"flat_streambuf overflow"};
|
||||||
|
// allocate a new buffer
|
||||||
auto const new_size = (std::min)(max_,
|
auto const new_size = (std::min)(max_,
|
||||||
std::max<std::size_t>(
|
std::max<std::size_t>(
|
||||||
detail::next_pow2(len + n), min_size));
|
detail::next_pow2(len + n), min_size));
|
||||||
auto const p = alloc_traits::allocate(
|
auto const p = alloc_traits::allocate(
|
||||||
this->member(), new_size);
|
this->member(), new_size);
|
||||||
std::memcpy(p, in_, len);
|
if(len > 0)
|
||||||
alloc_traits::deallocate(
|
{
|
||||||
this->member(), p_, dist(p_, end_));
|
BOOST_ASSERT(p);
|
||||||
|
BOOST_ASSERT(in_);
|
||||||
|
std::memcpy(p, in_, len);
|
||||||
|
alloc_traits::deallocate(
|
||||||
|
this->member(), p_, capacity());
|
||||||
|
}
|
||||||
p_ = p;
|
p_ = p;
|
||||||
in_ = p_;
|
in_ = p_;
|
||||||
out_ = in_ + len;
|
out_ = in_ + len;
|
||||||
@ -244,7 +254,7 @@ void
|
|||||||
basic_flat_streambuf<Allocator>::
|
basic_flat_streambuf<Allocator>::
|
||||||
reserve(std::size_t n)
|
reserve(std::size_t n)
|
||||||
{
|
{
|
||||||
if(n <= dist(p_, end_))
|
if(n <= capacity())
|
||||||
return;
|
return;
|
||||||
if(n > max_)
|
if(n > max_)
|
||||||
throw std::length_error{
|
throw std::length_error{
|
||||||
@ -256,9 +266,13 @@ reserve(std::size_t n)
|
|||||||
this->member(), new_size);
|
this->member(), new_size);
|
||||||
auto const len = size();
|
auto const len = size();
|
||||||
if(len > 0)
|
if(len > 0)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(p_);
|
||||||
|
BOOST_ASSERT(in_);
|
||||||
std::memcpy(p, in_, len);
|
std::memcpy(p, in_, len);
|
||||||
alloc_traits::deallocate(
|
alloc_traits::deallocate(
|
||||||
this->member(), p_, dist(p_, end_));
|
this->member(), p_, capacity());
|
||||||
|
}
|
||||||
p_ = p;
|
p_ = p;
|
||||||
in_ = p_;
|
in_ = p_;
|
||||||
out_ = p_ + len;
|
out_ = p_ + len;
|
||||||
@ -272,11 +286,13 @@ basic_flat_streambuf<Allocator>::
|
|||||||
shrink_to_fit()
|
shrink_to_fit()
|
||||||
{
|
{
|
||||||
auto const len = size();
|
auto const len = size();
|
||||||
if(len == dist(p_, end_))
|
if(len == capacity())
|
||||||
return;
|
return;
|
||||||
char* p;
|
char* p;
|
||||||
if(len > 0)
|
if(len > 0)
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(p_);
|
||||||
|
BOOST_ASSERT(in_);
|
||||||
p = alloc_traits::allocate(
|
p = alloc_traits::allocate(
|
||||||
this->member(), len);
|
this->member(), len);
|
||||||
std::memcpy(p, in_, len);
|
std::memcpy(p, in_, len);
|
||||||
|
Reference in New Issue
Block a user