mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-29 07:25:51 +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
7aa6b6b21d
commit
9bbcbd546b
@@ -231,16 +231,13 @@ private:
|
|||||||
using argument_type = element;
|
using argument_type = element;
|
||||||
using result_type = value_type;
|
using result_type = value_type;
|
||||||
|
|
||||||
const_buffers_type const* buffers_;
|
basic_streambuf const* streambuf_ = nullptr;
|
||||||
|
|
||||||
transform()
|
transform() = default;
|
||||||
: buffers_ (nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
transform (const_buffers_type const& buffers)
|
transform (basic_streambuf const& streambuf)
|
||||||
: buffers_ (&buffers)
|
: streambuf_ (&streambuf)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,11 +252,15 @@ public:
|
|||||||
transform, typename list_type::const_iterator,
|
transform, typename list_type::const_iterator,
|
||||||
value_type, value_type>;
|
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
|
const_iterator
|
||||||
begin() const
|
begin() const
|
||||||
{
|
{
|
||||||
return const_iterator (streambuf_->list_.begin(),
|
return const_iterator (streambuf_->list_.begin(),
|
||||||
transform(*this));
|
transform(*streambuf_));
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator
|
const_iterator
|
||||||
@@ -267,7 +268,7 @@ public:
|
|||||||
{
|
{
|
||||||
return const_iterator (streambuf_->out_ ==
|
return const_iterator (streambuf_->out_ ==
|
||||||
streambuf_->list_.end() ? streambuf_->list_.end() :
|
streambuf_->list_.end() ? streambuf_->list_.end() :
|
||||||
std::next(streambuf_->out_), transform(*this));
|
std::next(streambuf_->out_), transform(*streambuf_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -290,12 +291,11 @@ basic_streambuf<Allocator>::const_buffers_type::
|
|||||||
transform::operator() (element const& e) const ->
|
transform::operator() (element const& e) const ->
|
||||||
value_type const
|
value_type const
|
||||||
{
|
{
|
||||||
basic_streambuf const& streambuf = *buffers_->streambuf_;
|
|
||||||
return value_type (e.data(),
|
return value_type (e.data(),
|
||||||
(streambuf.out_ == streambuf.list_.end() ||
|
(streambuf_->out_ == streambuf_->list_.end() ||
|
||||||
&e != &*streambuf.out_) ? e.size() : streambuf.out_pos_) +
|
&e != &*streambuf_->out_) ? e.size() : streambuf_->out_pos_) +
|
||||||
(&e == &*streambuf.list_.begin() ?
|
(&e == &*streambuf_->list_.begin() ?
|
||||||
streambuf.in_pos_ : 0);
|
streambuf_->in_pos_ : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -312,16 +312,13 @@ private:
|
|||||||
using argument_type = element;
|
using argument_type = element;
|
||||||
using result_type = value_type;
|
using result_type = value_type;
|
||||||
|
|
||||||
mutable_buffers_type const* buffers_;
|
basic_streambuf const* streambuf_ = nullptr;
|
||||||
|
|
||||||
transform()
|
transform() = default;
|
||||||
: buffers_ (nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
transform (mutable_buffers_type const& buffers)
|
transform (basic_streambuf const& streambuf)
|
||||||
: buffers_ (&buffers)
|
: streambuf_ (&streambuf)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,18 +333,22 @@ public:
|
|||||||
transform, typename list_type::const_iterator,
|
transform, typename list_type::const_iterator,
|
||||||
value_type, value_type>;
|
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
|
const_iterator
|
||||||
begin() const
|
begin() const
|
||||||
{
|
{
|
||||||
return const_iterator (streambuf_->out_,
|
return const_iterator (streambuf_->out_,
|
||||||
transform(*this));
|
transform(*streambuf_));
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iterator
|
const_iterator
|
||||||
end() const
|
end() const
|
||||||
{
|
{
|
||||||
return const_iterator (streambuf_->list_.end(),
|
return const_iterator (streambuf_->list_.end(),
|
||||||
transform(*this));
|
transform(*streambuf_));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -368,10 +369,9 @@ basic_streambuf<Allocator>::mutable_buffers_type::
|
|||||||
transform::operator() (element const& e) const ->
|
transform::operator() (element const& e) const ->
|
||||||
value_type const
|
value_type const
|
||||||
{
|
{
|
||||||
basic_streambuf const& streambuf = *buffers_->streambuf_;
|
return value_type (e.data(), &e == &*std::prev(streambuf_->list_.end()) ?
|
||||||
return value_type (e.data(), &e == &*std::prev(streambuf.list_.end()) ?
|
streambuf_->out_end_ : e.size()) + (&e == &*streambuf_->out_ ?
|
||||||
streambuf.out_end_ : e.size()) + (&e == &*streambuf.out_ ?
|
streambuf_->out_pos_ : 0);
|
||||||
streambuf.out_pos_ : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user