mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Fix undefined behavior in pausation
This commit is contained in:
@ -2,6 +2,7 @@ Version 47
|
||||
|
||||
* Disable operator<< for buffer_body
|
||||
* buffer_size overload for basic_multi_buffer::const_buffers_type
|
||||
* Fix undefined behavior in pausation
|
||||
|
||||
API Changes:
|
||||
|
||||
|
@ -30,7 +30,7 @@ class pausation
|
||||
base() = default;
|
||||
base(base &&) = default;
|
||||
virtual ~base() = default;
|
||||
virtual void move(void* p) = 0;
|
||||
virtual base* move(void* p) = 0;
|
||||
virtual void operator()() = 0;
|
||||
};
|
||||
|
||||
@ -48,10 +48,10 @@ class pausation
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
base*
|
||||
move(void* p) override
|
||||
{
|
||||
::new(p) holder(std::move(*this));
|
||||
return ::new(p) holder(std::move(*this));
|
||||
}
|
||||
|
||||
void
|
||||
@ -100,9 +100,7 @@ public:
|
||||
{
|
||||
if(other.base_)
|
||||
{
|
||||
// type-pun
|
||||
base_ = reinterpret_cast<base*>(&buf_[0]);
|
||||
other.base_->move(buf_);
|
||||
base_ = other.base_->move(buf_);
|
||||
other.base_ = nullptr;
|
||||
}
|
||||
}
|
||||
@ -117,9 +115,7 @@ public:
|
||||
|
||||
if(other.base_)
|
||||
{
|
||||
// type-pun
|
||||
base_ = reinterpret_cast<base*>(&buf_[0]);
|
||||
other.base_->move(buf_);
|
||||
base_ = other.base_->move(buf_);
|
||||
other.base_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
@ -147,12 +143,11 @@ template<class F>
|
||||
void
|
||||
pausation::emplace(F&& f)
|
||||
{
|
||||
static_assert(sizeof(buf_type) >= sizeof(holder<F>),
|
||||
using type = holder<typename std::decay<F>::type>;
|
||||
static_assert(sizeof(buf_type) >= sizeof(type),
|
||||
"buffer too small");
|
||||
BOOST_ASSERT(! base_);
|
||||
::new(buf_) holder<F>(std::forward<F>(f));
|
||||
// type-pun
|
||||
base_ = reinterpret_cast<base*>(&buf_[0]);
|
||||
base_ = ::new(buf_) type{std::forward<F>(f)};
|
||||
}
|
||||
|
||||
} // detail
|
||||
|
@ -141,8 +141,7 @@ operator()(error_code ec, bool again)
|
||||
{
|
||||
// suspend
|
||||
d.state = 2;
|
||||
d.ws.wr_op_.template emplace<
|
||||
close_op>(std::move(*this));
|
||||
d.ws.wr_op_.emplace(std::move(*this));
|
||||
return;
|
||||
}
|
||||
if(d.ws.failed_ || d.ws.wr_close_)
|
||||
|
@ -139,8 +139,7 @@ operator()(error_code ec, bool again)
|
||||
{
|
||||
// suspend
|
||||
d.state = 2;
|
||||
d.ws.ping_op_.template emplace<
|
||||
ping_op>(std::move(*this));
|
||||
d.ws.ping_op_.emplace(std::move(*this));
|
||||
return;
|
||||
}
|
||||
if(d.ws.failed_ || d.ws.wr_close_)
|
||||
|
@ -456,8 +456,7 @@ operator()(error_code ec,
|
||||
// suspend
|
||||
d.state = do_pong_resume;
|
||||
BOOST_ASSERT(d.ws.wr_block_ != &d);
|
||||
d.ws.rd_op_.template emplace<
|
||||
read_frame_op>(std::move(*this));
|
||||
d.ws.rd_op_.emplace(std::move(*this));
|
||||
return;
|
||||
}
|
||||
d.state = do_pong;
|
||||
@ -496,8 +495,7 @@ operator()(error_code ec,
|
||||
{
|
||||
// suspend
|
||||
d.state = do_close_resume;
|
||||
d.ws.rd_op_.template emplace<
|
||||
read_frame_op>(std::move(*this));
|
||||
d.ws.rd_op_.emplace(std::move(*this));
|
||||
return;
|
||||
}
|
||||
d.state = do_close;
|
||||
@ -630,8 +628,7 @@ operator()(error_code ec,
|
||||
{
|
||||
// suspend
|
||||
d.state = do_fail + 2;
|
||||
d.ws.rd_op_.template emplace<
|
||||
read_frame_op>(std::move(*this));
|
||||
d.ws.rd_op_.emplace(std::move(*this));
|
||||
return;
|
||||
}
|
||||
// fall through
|
||||
|
@ -491,8 +491,7 @@ operator()(error_code ec,
|
||||
{
|
||||
// suspend
|
||||
d.state = do_maybe_suspend + 1;
|
||||
d.ws.wr_op_.template emplace<
|
||||
write_frame_op>(std::move(*this));
|
||||
d.ws.wr_op_.emplace(std::move(*this));
|
||||
return;
|
||||
}
|
||||
if(d.ws.failed_ || d.ws.wr_close_)
|
||||
|
Reference in New Issue
Block a user