diff --git a/Source/dvlnet/frame_queue.cpp b/Source/dvlnet/frame_queue.cpp index 05936d4cd..73e321c01 100644 --- a/Source/dvlnet/frame_queue.cpp +++ b/Source/dvlnet/frame_queue.cpp @@ -2,11 +2,19 @@ #include +#include "appfat.h" #include "dvlnet/packet.h" +#include "utils/attributes.h" namespace devilution { namespace net { +#if DVL_EXCEPTIONS +#define FRAME_QUEUE_ERROR throw frame_queue_exception() +#else +#define FRAME_QUEUE_ERROR app_fatal("frame queue error") +#endif + framesize_t frame_queue::Size() const { return current_size; @@ -15,7 +23,7 @@ framesize_t frame_queue::Size() const buffer_t frame_queue::Read(framesize_t s) { if (current_size < s) - throw frame_queue_exception(); + FRAME_QUEUE_ERROR; buffer_t ret; while (s > 0 && s >= buffer_deque.front().size()) { s -= buffer_deque.front().size(); @@ -50,7 +58,7 @@ bool frame_queue::PacketReady() auto szbuf = Read(sizeof(framesize_t)); std::memcpy(&nextsize, &szbuf[0], sizeof(framesize_t)); if (nextsize == 0) - throw frame_queue_exception(); + FRAME_QUEUE_ERROR; } return Size() >= nextsize; } @@ -58,7 +66,7 @@ bool frame_queue::PacketReady() buffer_t frame_queue::ReadPacket() { if (nextsize == 0 || Size() < nextsize) - throw frame_queue_exception(); + FRAME_QUEUE_ERROR; auto ret = Read(nextsize); nextsize = 0; return ret; diff --git a/Source/dvlnet/packet.cpp b/Source/dvlnet/packet.cpp index 57fd51bbe..5c215d341 100644 --- a/Source/dvlnet/packet.cpp +++ b/Source/dvlnet/packet.cpp @@ -107,7 +107,11 @@ void CheckPacketTypeOneOf(std::initializer_list expectedTypes, std: for (std::uint8_t packetType : expectedTypes) if (actualType == packetType) return; +#if DVL_EXCEPTIONS throw wrong_packet_type_exception(expectedTypes, actualType); +#else + app_fatal("wrong packet type"); +#endif } } // namespace @@ -191,7 +195,11 @@ void packet_in::Create(buffer_t buf) { assert(!have_encrypted && !have_decrypted); if (buf.size() < sizeof(packet_type) + 2 * sizeof(plr_t)) +#if DVL_EXCEPTIONS throw packet_exception(); +#else + app_fatal("invalid packet"); +#endif decrypted_buffer = std::move(buf); have_decrypted = true; diff --git a/Source/dvlnet/packet.h b/Source/dvlnet/packet.h index 0be840dd7..a306a422f 100644 --- a/Source/dvlnet/packet.h +++ b/Source/dvlnet/packet.h @@ -10,7 +10,9 @@ #include #endif +#include "appfat.h" #include "dvlnet/abstract_net.h" +#include "utils/attributes.h" #include "utils/stubs.h" namespace devilution { @@ -201,7 +203,11 @@ template void packet_in::process_element(T &x) { if (decrypted_buffer.size() < sizeof(T)) +#if DVL_EXCEPTIONS throw packet_exception(); +#else + app_fatal("invalid packet"); +#endif std::memcpy(&x, decrypted_buffer.data(), sizeof(T)); decrypted_buffer.erase(decrypted_buffer.begin(), decrypted_buffer.begin() + sizeof(T)); diff --git a/Source/utils/attributes.h b/Source/utils/attributes.h index 16214fd0d..ec9340c68 100644 --- a/Source/utils/attributes.h +++ b/Source/utils/attributes.h @@ -50,3 +50,9 @@ #else #define DVL_REINITIALIZES #endif + +#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || FMT_MSC_VER && !_HAS_EXCEPTIONS +#define DVL_EXCEPTIONS 0 +#else +#define DVL_EXCEPTIONS 1 +#endif diff --git a/Source/utils/log.hpp b/Source/utils/log.hpp index 08c7fc277..23cc474c3 100644 --- a/Source/utils/log.hpp +++ b/Source/utils/log.hpp @@ -49,9 +49,13 @@ std::string format(string_view fmt, Args &&...args) } FMT_CATCH(const fmt::format_error &e) { +#if FMT_EXCEPTIONS + // e.what() is undefined if exceptions are disabled, so we wrap the whole block + // with an `FMT_EXCEPTIONS` check. std::string error = fmt::format("Format error, fmt: {}, error: {}", fmt, e.what()); SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "%s", error.c_str()); app_fatal(error); +#endif } }