diff --git a/CHANGELOG.md b/CHANGELOG.md index 65be5b430f..b39fa04701 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Version 158: * Tidy up websocket docs * Examples set reuse_address(true) * Advanced servers support clean shutdown via SIGINT or SIGTERM +* DynamicBuffer input areas are not mutable -------------------------------------------------------------------------------- diff --git a/doc/qbk/09_releases.qbk b/doc/qbk/09_releases.qbk index 85197fad9f..0b45efc236 100644 --- a/doc/qbk/09_releases.qbk +++ b/doc/qbk/09_releases.qbk @@ -156,7 +156,9 @@ to update to the latest Boost release. * [link beast.ref.boost__beast__websocket__stream.control_callback `websocket::stream::control_callback`] now copies or moves the function object. - +* ([issue 1014]) DynamicBuffer input areas are not mutable. + Actions required: do not attempt to write to input areas of dynamic + buffers. diff --git a/include/boost/beast/core/flat_buffer.hpp b/include/boost/beast/core/flat_buffer.hpp index 0ccd16bc64..11a18fdcb4 100644 --- a/include/boost/beast/core/flat_buffer.hpp +++ b/include/boost/beast/core/flat_buffer.hpp @@ -84,7 +84,7 @@ class basic_flat_buffer using allocator_type = Allocator; /// The type used to represent the input sequence as a list of buffers. - using const_buffers_type = boost::asio::mutable_buffer; + using const_buffers_type = boost::asio::const_buffer; /// The type used to represent the output sequence as a list of buffers. using mutable_buffers_type = boost::asio::mutable_buffer; diff --git a/include/boost/beast/core/flat_static_buffer.hpp b/include/boost/beast/core/flat_static_buffer.hpp index 141ae552c1..c8eae90945 100644 --- a/include/boost/beast/core/flat_static_buffer.hpp +++ b/include/boost/beast/core/flat_static_buffer.hpp @@ -52,7 +52,7 @@ class flat_static_buffer_base This buffer sequence is guaranteed to have length 1. */ - using const_buffers_type = boost::asio::mutable_buffer; + using const_buffers_type = boost::asio::const_buffer; /** The type used to represent the output sequence as a list of buffers. diff --git a/include/boost/beast/core/impl/multi_buffer.ipp b/include/boost/beast/core/impl/multi_buffer.ipp index 7b66694cb3..e7ae541f9c 100644 --- a/include/boost/beast/core/impl/multi_buffer.ipp +++ b/include/boost/beast/core/impl/multi_buffer.ipp @@ -132,7 +132,7 @@ class basic_multi_buffer::const_buffers_type const_buffers_type(basic_multi_buffer const& b); public: - using value_type = boost::asio::mutable_buffer; + using value_type = boost::asio::const_buffer; class const_iterator; diff --git a/include/boost/beast/core/impl/static_buffer.ipp b/include/boost/beast/core/impl/static_buffer.ipp index d93a1e6911..2fdb2d9a8a 100644 --- a/include/boost/beast/core/impl/static_buffer.ipp +++ b/include/boost/beast/core/impl/static_buffer.ipp @@ -35,9 +35,30 @@ static_buffer_base:: data() const -> const_buffers_type { - using boost::asio::mutable_buffer; + using boost::asio::const_buffer; const_buffers_type result; if(in_off_ + in_size_ <= capacity_) + { + result[0] = const_buffer{begin_ + in_off_, in_size_}; + result[1] = const_buffer{begin_, 0}; + } + else + { + result[0] = const_buffer{begin_ + in_off_, capacity_ - in_off_}; + result[1] = const_buffer{begin_, in_size_ - (capacity_ - in_off_)}; + } + return result; +} + +inline +auto +static_buffer_base:: +mutable_data() -> + mutable_buffers_type +{ + using boost::asio::mutable_buffer; + mutable_buffers_type result; + if(in_off_ + in_size_ <= capacity_) { result[0] = mutable_buffer{begin_ + in_off_, in_size_}; result[1] = mutable_buffer{begin_, 0}; diff --git a/include/boost/beast/core/static_buffer.hpp b/include/boost/beast/core/static_buffer.hpp index 05496c4018..86f06b1efd 100644 --- a/include/boost/beast/core/static_buffer.hpp +++ b/include/boost/beast/core/static_buffer.hpp @@ -52,7 +52,7 @@ class static_buffer_base public: /// The type used to represent the input sequence as a list of buffers. using const_buffers_type = - std::array; + std::array; /// The type used to represent the output sequence as a list of buffers. using mutable_buffers_type = @@ -94,6 +94,11 @@ class static_buffer_base const_buffers_type data() const; + /** Get a mutable list of buffers that represent the input sequence. + */ + mutable_buffers_type + mutable_data(); + /** Get a list of buffers that represent the output sequence, with the given size. @param size The number of bytes to request. diff --git a/include/boost/beast/websocket/impl/close.ipp b/include/boost/beast/websocket/impl/close.ipp index c8796cb304..052ffe50f0 100644 --- a/include/boost/beast/websocket/impl/close.ipp +++ b/include/boost/beast/websocket/impl/close.ipp @@ -228,7 +228,7 @@ operator()( d.ws.rd_close_ = true; auto const mb = buffers_prefix( clamp(d.ws.rd_fh_.len), - d.ws.rd_buf_.data()); + d.ws.rd_buf_.mutable_data()); if(d.ws.rd_fh_.len > 0 && d.ws.rd_fh_.mask) detail::mask_inplace(mb, d.ws.rd_key_); detail::read_close(d.ws.cr_, mb, d.ev); @@ -370,7 +370,7 @@ close(close_reason const& cr, error_code& ec) rd_close_ = true; auto const mb = buffers_prefix( clamp(rd_fh_.len), - rd_buf_.data()); + rd_buf_.mutable_data()); if(rd_fh_.len > 0 && rd_fh_.mask) detail::mask_inplace(mb, rd_key_); detail::read_close(cr_, mb, result); diff --git a/include/boost/beast/websocket/impl/read.ipp b/include/boost/beast/websocket/impl/read.ipp index 387b765a1f..27c659e6c0 100644 --- a/include/boost/beast/websocket/impl/read.ipp +++ b/include/boost/beast/websocket/impl/read.ipp @@ -253,7 +253,7 @@ operator()( if(ws_.rd_fh_.len > 0 && ws_.rd_fh_.mask) detail::mask_inplace(buffers_prefix( clamp(ws_.rd_fh_.len), - ws_.rd_buf_.data()), + ws_.rd_buf_.mutable_data()), ws_.rd_key_); if(detail::is_control(ws_.rd_fh_.op)) { @@ -440,7 +440,7 @@ operator()( ws_.rd_buf_.commit(bytes_transferred); if(ws_.rd_fh_.mask) detail::mask_inplace(buffers_prefix(clamp( - ws_.rd_remain_), ws_.rd_buf_.data()), + ws_.rd_remain_), ws_.rd_buf_.mutable_data()), ws_.rd_key_); } if(ws_.rd_buf_.size() > 0) @@ -528,7 +528,7 @@ operator()( if(ws_.rd_fh_.mask) detail::mask_inplace( buffers_prefix(clamp(ws_.rd_remain_), - ws_.rd_buf_.data()), ws_.rd_key_); + ws_.rd_buf_.mutable_data()), ws_.rd_key_); did_read_ = true; } zlib::z_params zs; @@ -1049,7 +1049,7 @@ loop: // of the buffer holding payload data. if(rd_fh_.len > 0 && rd_fh_.mask) detail::mask_inplace(buffers_prefix( - clamp(rd_fh_.len), rd_buf_.data()), + clamp(rd_fh_.len), rd_buf_.mutable_data()), rd_key_); if(detail::is_control(rd_fh_.op)) { @@ -1151,7 +1151,7 @@ loop: if(rd_fh_.mask) detail::mask_inplace( buffers_prefix(clamp(rd_remain_), - rd_buf_.data()), rd_key_); + rd_buf_.mutable_data()), rd_key_); } if(rd_buf_.size() > 0) { @@ -1258,7 +1258,7 @@ loop: if(rd_fh_.mask) detail::mask_inplace( buffers_prefix(clamp(rd_remain_), - rd_buf_.data()), rd_key_); + rd_buf_.mutable_data()), rd_key_); auto const in = buffers_prefix( clamp(rd_remain_), buffers_front( rd_buf_.data()));