From 0edd53f5f864b9f452dc231e24b438f9d50ff436 Mon Sep 17 00:00:00 2001 From: "Scott E. Graves" Date: Sat, 27 Sep 2025 18:18:32 -0500 Subject: [PATCH] fix crash --- .../librepertory/src/comm/packet/common.cpp | 57 +++++++++++-------- .../src/comm/packet/packet_client.cpp | 13 +++-- .../src/comm/packet/packet_server.cpp | 5 ++ 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/repertory/librepertory/src/comm/packet/common.cpp b/repertory/librepertory/src/comm/packet/common.cpp index 630a8d15..e39ebef7 100644 --- a/repertory/librepertory/src/comm/packet/common.cpp +++ b/repertory/librepertory/src/comm/packet/common.cpp @@ -84,46 +84,55 @@ void apply_common_socket_properties(boost::asio::ip::tcp::socket &sock) { } template -void run_with_deadline(boost::asio::io_context &io_ctx, - boost::asio::ip::tcp::socket &sock, op_t &&operation, - std::chrono::milliseconds deadline, - std::string_view event_name, - std::string_view function_name) { +static void run_with_deadline(boost::asio::io_context &io_ctx, + boost::asio::ip::tcp::socket &sock, + op_t &&operation, + std::chrono::milliseconds deadline, + const std::string &event_name, + const std::string &function_name) { deadline = std::max(deadline, std::chrono::milliseconds{250}); - bool done = false; - bool timed_out = false; + struct request_state final { + std::atomic done{false}; + std::atomic timed_out{false}; + boost::system::error_code err; + }; + auto state = std::make_shared(); boost::asio::steady_timer timer{io_ctx}; timer.expires_after(deadline); - timer.async_wait([&done, &sock, &timed_out](auto &&err_) { - if (not err_ && not done) { - timed_out = true; - sock.cancel(); + + timer.async_wait([state, &sock](auto &&err) { + if (not err && not state->done) { + state->timed_out = true; + boost::system::error_code ignored_ec; + [[maybe_unused]] auto res = sock.cancel(ignored_ec); } }); - boost::system::error_code err{}; - operation([&done, &err](auto &&err_) { - err = err_; - done = true; + operation([state](auto &&err) { + state->err = err; + state->done = true; }); io_ctx.restart(); - while (not done) { + while (not state->done && not state->timed_out) { io_ctx.run_one(); } + timer.cancel(); - if (timed_out) { + io_ctx.poll(); + + if (state->timed_out) { repertory::event_system::instance().raise( std::string(event_name), std::string(function_name)); - throw std::runtime_error(std::string(event_name) + " timed-out"); + throw std::runtime_error(event_name + " timed-out"); } - if (err) { - throw std::runtime_error(std::string(event_name) + " failed|err|" + - err.message()); + if (state->err) { + throw std::runtime_error(event_name + " failed|err|" + + state->err.message()); } } @@ -140,7 +149,7 @@ void connect_with_deadline( boost::asio::async_connect( sock, endpoints, [handler](auto &&err, auto &&) { handler(err); }); }, - deadline, "connect", function_name); + deadline, "connect", std::string{function_name}); } void read_exact_with_deadline(boost::asio::io_context &io_ctx, @@ -167,7 +176,7 @@ void read_exact_with_deadline(boost::asio::io_context &io_ctx, handler(err); }); }, - deadline, "read", function_name); + deadline, "read", std::string{function_name}); if (bytes_read == 0U) { throw std::runtime_error("0 bytes read"); @@ -200,7 +209,7 @@ void write_all_with_deadline(boost::asio::io_context &io_ctx, handler(err); }); }, - deadline, "write", function_name); + deadline, "write", std::string{function_name}); if (bytes_written == 0U) { throw std::runtime_error("0 bytes written"); diff --git a/repertory/librepertory/src/comm/packet/packet_client.cpp b/repertory/librepertory/src/comm/packet/packet_client.cpp index cc3a5c8b..de47627e 100644 --- a/repertory/librepertory/src/comm/packet/packet_client.cpp +++ b/repertory/librepertory/src/comm/packet/packet_client.cpp @@ -58,10 +58,11 @@ packet_client::~packet_client() { void packet_client::close(client &cli) noexcept { boost::system::error_code err1; - auto res = cli.socket.shutdown(boost::asio::socket_base::shutdown_both, err1); + [[maybe_unused]] auto res = + cli.socket.shutdown(boost::asio::socket_base::shutdown_both, err1); boost::system::error_code err2; - res = cli.socket.close(err2); + [[maybe_unused]] auto res2 = cli.socket.close(err2); } void packet_client::close_all() { @@ -244,8 +245,12 @@ auto packet_client::read_packet(client &cli, boost::asio::io_context &ctx, std::memcpy(&to_read, buffer.data(), sizeof(to_read)); boost::endian::big_to_native_inplace(to_read); - if (to_read == 0U || to_read > comm::max_packet_bytes) { - return utils::from_api_error(api_error::comm_error); + if (to_read > comm::max_packet_bytes) { + throw std::runtime_error(fmt::format("packet too large|size|{}", to_read)); + } + + if (to_read < utils::encryption::encryption_header_size) { + throw std::runtime_error(fmt::format("packet too small|size|{}", to_read)); } buffer.resize(to_read); diff --git a/repertory/librepertory/src/comm/packet/packet_server.cpp b/repertory/librepertory/src/comm/packet/packet_server.cpp index 60e5e16a..102696e2 100644 --- a/repertory/librepertory/src/comm/packet/packet_server.cpp +++ b/repertory/librepertory/src/comm/packet/packet_server.cpp @@ -289,6 +289,11 @@ void packet_server::read_packet(std::shared_ptr conn, fmt::format("packet too large|size|{}", data_size)); } + if (data_size < utils::encryption::encryption_header_size) { + throw std::runtime_error( + fmt::format("packet too small|size|{}", data_size)); + } + auto should_send_response = true; auto response = std::make_shared(); conn->buffer.resize(data_size);