mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 13:27:33 +02:00
Fix ostream prepare calculation for low limits:
This resolves an issue where the ostream could try to exceeed the configured maximum size of a dynamic buffer when the maximum is set to a very low number.
This commit is contained in:
@ -13,6 +13,7 @@ Version 200
|
|||||||
* Optimize for size on buffers_cat preconditions
|
* Optimize for size on buffers_cat preconditions
|
||||||
* Refactor buffers_suffix
|
* Refactor buffers_suffix
|
||||||
* Tidy up flat_buffer tests
|
* Tidy up flat_buffer tests
|
||||||
|
* Fix ostream prepare calculation for low limits
|
||||||
|
|
||||||
API Changes:
|
API Changes:
|
||||||
|
|
||||||
|
@ -83,9 +83,7 @@ class ostream_buffer
|
|||||||
using traits_type = typename
|
using traits_type = typename
|
||||||
std::basic_streambuf<CharT, Traits>::traits_type;
|
std::basic_streambuf<CharT, Traits>::traits_type;
|
||||||
|
|
||||||
static std::size_t constexpr max_size = 512;
|
DynamicBuffer& b_;
|
||||||
|
|
||||||
DynamicBuffer& buf_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ostream_buffer(ostream_buffer&&) = default;
|
ostream_buffer(ostream_buffer&&) = default;
|
||||||
@ -97,8 +95,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
ostream_buffer(DynamicBuffer& buf)
|
ostream_buffer(DynamicBuffer& b)
|
||||||
: buf_(buf)
|
: b_(b)
|
||||||
{
|
{
|
||||||
prepare();
|
prepare();
|
||||||
}
|
}
|
||||||
@ -130,8 +128,13 @@ private:
|
|||||||
void
|
void
|
||||||
prepare()
|
prepare()
|
||||||
{
|
{
|
||||||
auto bs = buf_.prepare(
|
static std::size_t constexpr max_size = 65536;
|
||||||
read_size_or_throw(buf_, max_size));
|
auto const max_prepare = std::min<std::size_t>(
|
||||||
|
std::max<std::size_t>(
|
||||||
|
512, b_.capacity() - b_.size()),
|
||||||
|
std::min<std::size_t>(
|
||||||
|
max_size, b_.max_size() - b_.size()));
|
||||||
|
auto const bs = b_.prepare(max_prepare);
|
||||||
auto const b = buffers_front(bs);
|
auto const b = buffers_front(bs);
|
||||||
auto const p = static_cast<CharT*>(b.data());
|
auto const p = static_cast<CharT*>(b.data());
|
||||||
this->setp(p,
|
this->setp(p,
|
||||||
@ -141,7 +144,7 @@ private:
|
|||||||
void
|
void
|
||||||
flush(int extra = 0)
|
flush(int extra = 0)
|
||||||
{
|
{
|
||||||
buf_.commit(
|
b_.commit(
|
||||||
(this->pptr() - this->pbase() + extra) *
|
(this->pptr() - this->pbase() + extra) *
|
||||||
sizeof(CharT));
|
sizeof(CharT));
|
||||||
}
|
}
|
||||||
@ -162,9 +165,7 @@ class ostream_buffer
|
|||||||
using traits_type = typename
|
using traits_type = typename
|
||||||
std::basic_streambuf<CharT, Traits>::traits_type;
|
std::basic_streambuf<CharT, Traits>::traits_type;
|
||||||
|
|
||||||
static std::size_t constexpr max_size = 512;
|
DynamicBuffer& b_;
|
||||||
|
|
||||||
DynamicBuffer& buf_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ostream_buffer(ostream_buffer&&) = delete;
|
ostream_buffer(ostream_buffer&&) = delete;
|
||||||
@ -176,8 +177,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
ostream_buffer(DynamicBuffer& buf)
|
ostream_buffer(DynamicBuffer& b)
|
||||||
: buf_(buf)
|
: b_(b)
|
||||||
{
|
{
|
||||||
prepare();
|
prepare();
|
||||||
}
|
}
|
||||||
@ -209,8 +210,13 @@ private:
|
|||||||
void
|
void
|
||||||
prepare()
|
prepare()
|
||||||
{
|
{
|
||||||
auto bs = buf_.prepare(
|
static std::size_t constexpr max_size = 65536;
|
||||||
read_size_or_throw(buf_, max_size));
|
auto const max_prepare = std::min<std::size_t>(
|
||||||
|
std::max<std::size_t>(
|
||||||
|
512, b_.capacity() - b_.size()),
|
||||||
|
std::min<std::size_t>(
|
||||||
|
max_size, b_.max_size() - b_.size()));
|
||||||
|
auto const bs = b_.prepare(max_prepare);
|
||||||
auto const b = buffers_front(bs);
|
auto const b = buffers_front(bs);
|
||||||
auto const p = static_cast<CharT*>(b.data());
|
auto const p = static_cast<CharT*>(b.data());
|
||||||
this->setp(p,
|
this->setp(p,
|
||||||
@ -220,7 +226,7 @@ private:
|
|||||||
void
|
void
|
||||||
flush(int extra = 0)
|
flush(int extra = 0)
|
||||||
{
|
{
|
||||||
buf_.commit(
|
b_.commit(
|
||||||
(this->pptr() - this->pbase() + extra) *
|
(this->pptr() - this->pbase() + extra) *
|
||||||
sizeof(CharT));
|
sizeof(CharT));
|
||||||
}
|
}
|
||||||
@ -242,17 +248,17 @@ class ostream_helper<
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit
|
explicit
|
||||||
ostream_helper(DynamicBuffer& buf);
|
ostream_helper(DynamicBuffer& b);
|
||||||
|
|
||||||
ostream_helper(ostream_helper&& other);
|
ostream_helper(ostream_helper&& other);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class DynamicBuffer, class CharT, class Traits>
|
template<class DynamicBuffer, class CharT, class Traits>
|
||||||
ostream_helper<DynamicBuffer, CharT, Traits, true>::
|
ostream_helper<DynamicBuffer, CharT, Traits, true>::
|
||||||
ostream_helper(DynamicBuffer& buf)
|
ostream_helper(DynamicBuffer& b)
|
||||||
: std::basic_ostream<CharT, Traits>(
|
: std::basic_ostream<CharT, Traits>(
|
||||||
&this->osb_)
|
&this->osb_)
|
||||||
, osb_(buf)
|
, osb_(b)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,11 +299,11 @@ class ostream_helper<
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit
|
explicit
|
||||||
ostream_helper(DynamicBuffer& buf)
|
ostream_helper(DynamicBuffer& b)
|
||||||
: ostream_helper_base<ostream_buffer<
|
: ostream_helper_base<ostream_buffer<
|
||||||
DynamicBuffer, CharT, Traits, false>>(
|
DynamicBuffer, CharT, Traits, false>>(
|
||||||
new ostream_buffer<DynamicBuffer,
|
new ostream_buffer<DynamicBuffer,
|
||||||
CharT, Traits, false>(buf))
|
CharT, Traits, false>(b))
|
||||||
, std::basic_ostream<CharT, Traits>(this->member.get())
|
, std::basic_ostream<CharT, Traits>(this->member.get())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user