The move constructor and move assignment operator of openssl_stream / wolfssl_stream leave the internal impl::s_ reference bound to the source object's stream_, not the destination's.
#include <boost/capy.hpp>
#include <boost/corosio/openssl_stream.hpp>
#include <boost/corosio/tcp_socket.hpp>
#include <boost/corosio/io_context.hpp>
using namespace boost;
capy::task<>
async_main()
{
corosio::tls_context ctx;
corosio::tcp_socket sock(co_await capy::this_coro::executor);
corosio::openssl_stream a(&sock, ctx);
corosio::openssl_stream b(std::move(a)); // b.impl_->s_ now references a.stream_
co_await b.handshake(corosio::openssl_stream::client); // UB
}
int
main()
{
corosio::io_context ioc;
capy::run_async(ioc.get_executor())(async_main());
ioc.run();
}
The move constructor and move assignment operator of
openssl_stream/wolfssl_streamleave the internalimpl::s_reference bound to the source object'sstream_, not the destination's.