mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-18 18:15:50 +00:00
Fix streambuf bug:
The buffers_type::iterator could hold a pointer to a buffers_type that was destroyed. This changes buffers_type::iterator to point to the original streambuf instead, which always outlives the iterator.
This commit is contained in:
committed by
Tom Ritchford
parent
982dc6aa8c
commit
49378ab7fe
@@ -231,16 +231,13 @@ private:
|
||||
using argument_type = element;
|
||||
using result_type = value_type;
|
||||
|
||||
const_buffers_type const* buffers_;
|
||||
basic_streambuf const* streambuf_ = nullptr;
|
||||
|
||||
transform()
|
||||
: buffers_ (nullptr)
|
||||
{
|
||||
}
|
||||
transform() = default;
|
||||
|
||||
explicit
|
||||
transform (const_buffers_type const& buffers)
|
||||
: buffers_ (&buffers)
|
||||
transform (basic_streambuf const& streambuf)
|
||||
: streambuf_ (&streambuf)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -255,11 +252,15 @@ public:
|
||||
transform, typename list_type::const_iterator,
|
||||
value_type, value_type>;
|
||||
|
||||
const_buffers_type() = default;
|
||||
const_buffers_type (const_buffers_type const&) = default;
|
||||
const_buffers_type& operator= (const_buffers_type const&) = default;
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return const_iterator (streambuf_->list_.begin(),
|
||||
transform(*this));
|
||||
transform(*streambuf_));
|
||||
}
|
||||
|
||||
const_iterator
|
||||
@@ -267,7 +268,7 @@ public:
|
||||
{
|
||||
return const_iterator (streambuf_->out_ ==
|
||||
streambuf_->list_.end() ? streambuf_->list_.end() :
|
||||
std::next(streambuf_->out_), transform(*this));
|
||||
std::next(streambuf_->out_), transform(*streambuf_));
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -290,12 +291,11 @@ basic_streambuf<Allocator>::const_buffers_type::
|
||||
transform::operator() (element const& e) const ->
|
||||
value_type const
|
||||
{
|
||||
basic_streambuf const& streambuf = *buffers_->streambuf_;
|
||||
return value_type (e.data(),
|
||||
(streambuf.out_ == streambuf.list_.end() ||
|
||||
&e != &*streambuf.out_) ? e.size() : streambuf.out_pos_) +
|
||||
(&e == &*streambuf.list_.begin() ?
|
||||
streambuf.in_pos_ : 0);
|
||||
(streambuf_->out_ == streambuf_->list_.end() ||
|
||||
&e != &*streambuf_->out_) ? e.size() : streambuf_->out_pos_) +
|
||||
(&e == &*streambuf_->list_.begin() ?
|
||||
streambuf_->in_pos_ : 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -312,16 +312,13 @@ private:
|
||||
using argument_type = element;
|
||||
using result_type = value_type;
|
||||
|
||||
mutable_buffers_type const* buffers_;
|
||||
basic_streambuf const* streambuf_ = nullptr;
|
||||
|
||||
transform()
|
||||
: buffers_ (nullptr)
|
||||
{
|
||||
}
|
||||
transform() = default;
|
||||
|
||||
explicit
|
||||
transform (mutable_buffers_type const& buffers)
|
||||
: buffers_ (&buffers)
|
||||
transform (basic_streambuf const& streambuf)
|
||||
: streambuf_ (&streambuf)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -336,18 +333,22 @@ public:
|
||||
transform, typename list_type::const_iterator,
|
||||
value_type, value_type>;
|
||||
|
||||
mutable_buffers_type() = default;
|
||||
mutable_buffers_type (mutable_buffers_type const&) = default;
|
||||
mutable_buffers_type& operator= (mutable_buffers_type const&) = default;
|
||||
|
||||
const_iterator
|
||||
begin() const
|
||||
{
|
||||
return const_iterator (streambuf_->out_,
|
||||
transform(*this));
|
||||
transform(*streambuf_));
|
||||
}
|
||||
|
||||
const_iterator
|
||||
end() const
|
||||
{
|
||||
return const_iterator (streambuf_->list_.end(),
|
||||
transform(*this));
|
||||
transform(*streambuf_));
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -368,10 +369,9 @@ basic_streambuf<Allocator>::mutable_buffers_type::
|
||||
transform::operator() (element const& e) const ->
|
||||
value_type const
|
||||
{
|
||||
basic_streambuf const& streambuf = *buffers_->streambuf_;
|
||||
return value_type (e.data(), &e == &*std::prev(streambuf.list_.end()) ?
|
||||
streambuf.out_end_ : e.size()) + (&e == &*streambuf.out_ ?
|
||||
streambuf.out_pos_ : 0);
|
||||
return value_type (e.data(), &e == &*std::prev(streambuf_->list_.end()) ?
|
||||
streambuf_->out_end_ : e.size()) + (&e == &*streambuf_->out_ ?
|
||||
streambuf_->out_pos_ : 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user