diff --git a/examples/sound-player/main.cpp b/examples/sound-player/main.cpp index 4a8597668..eaff53873 100644 --- a/examples/sound-player/main.cpp +++ b/examples/sound-player/main.cpp @@ -1,4 +1,5 @@ #include //For noise +#include #include "sleepy_discord/sleepy_discord.h" #include "IO_file.h" //For music diff --git a/include/sleepy_discord/asio_websocketconnection.h b/include/sleepy_discord/asio_websocketconnection.h index 7a8dacd6a..54238045b 100644 --- a/include/sleepy_discord/asio_websocketconnection.h +++ b/include/sleepy_discord/asio_websocketconnection.h @@ -247,7 +247,6 @@ namespace SleepyDiscord { headers.insert(std::make_pair(headerFieldLeft, std::move(headerFieldRight))); } offset += 2; // + 2 to skip end of header - const auto bodyStart = offset; // easyer to write it like this, but a map of functions might be faster { @@ -478,7 +477,7 @@ namespace SleepyDiscord { void receiveFullHandshake(std::shared_ptr> responsePtr, const std::size_t length, int score = 0) { const static std::array endOfHandshake = { '\r', '\n', '\r', '\n' }; - for (int i = 0; i < length; i += 1) { + for (std::size_t i = 0; i < length; i += 1) { if (responsePtr->data()[i] == endOfHandshake[score]) { score += 1; if (score == 4) { @@ -538,7 +537,7 @@ namespace SleepyDiscord { std::memcpy(&secondByte, &temp, 1); } - constexpr int8_t hasMaskByte = 1; constexpr int8_t hasMaskBit = static_cast(0b1000'0000); + constexpr int8_t hasMaskBit = static_cast(0b1000'0000); bool hasMask = (secondByte & hasMaskBit) == hasMaskBit; const std::size_t maskLength = hasMask ? sizeof(uint32_t) : 0; if (hasMask) { // Servers shouldn't sent masked payloads @@ -546,7 +545,7 @@ namespace SleepyDiscord { return; } - constexpr int8_t hasExtendedLengthByte = 1; constexpr int8_t hasExtendedLength = static_cast(0b0111'1111); + constexpr int8_t hasExtendedLength = static_cast(0b0111'1111); int8_t length7Bit = secondByte & hasExtendedLength; std::size_t lengthOfLength; switch (length7Bit) { @@ -589,7 +588,7 @@ namespace SleepyDiscord { auto self = shared_from_this(); std::istream inputStream(readBuffer.get()); int extendedLengthPrefixLength; - uint64_t payloadLength; + std::size_t payloadLength; switch (frame.length7Bit) { case 126: { constexpr std::size_t size = sizeof(uint16_t); @@ -609,7 +608,19 @@ namespace SleepyDiscord { inputStream.read(temp.data(), networkInt.size()); std::memcpy(networkInt.data(), temp.data(), networkInt.size()); } - payloadLength = net2System64(networkInt); + uint64_t temp = net2System64(networkInt); + + constexpr bool pointerIsTooSmall = (std::numeric_limits::max)() < (std::numeric_limits::max)(); + if ( // on a 32 bit or 16 bit system, we can't put the message in memory + // the compiler should be smart enough to get rid of this on 64-bit systems + pointerIsTooSmall && ((std::numeric_limits::max)() < payloadLength) + ) { // doubt that Discord would ever sent a 4 GB websocket payload, so just kill it + std::cerr << "Can't read message larger then max pointer value\n"; + disconnect(1009, "sizeof(PTR)(temp); } break; default: extendedLengthPrefixLength = 0; @@ -619,11 +630,11 @@ namespace SleepyDiscord { const std::size_t maskStart = 2 + static_cast(extendedLengthPrefixLength); const std::size_t payloadStart = maskStart + frame.maskLength; - const std::size_t fullMessageLength = payloadStart + payloadLength; + const std::size_t leftOverLength = length - payloadStart; - if (length < fullMessageLength) { + if (leftOverLength < payloadLength) { // we don't have the whole message, loop receive until we have the whole message - const std::size_t bytesLeftToGet = fullMessageLength - length; + const std::size_t bytesLeftToGet = payloadLength - leftOverLength; asio::async_read(*(self->socketPtr), *readBuffer, asio::transfer_at_least(bytesLeftToGet), [self, readBuffer, frame, payloadLength, bytesLeftToGet](const asio::error_code& err, const std::size_t length) { if (err) { std::cerr << "failed to read whole\n"; @@ -636,7 +647,7 @@ namespace SleepyDiscord { else { // we have the whole message, we don't need to read again self->onPayload(frame.opCode, readBuffer, payloadLength); - afterPayload(length - fullMessageLength, readBuffer); + afterPayload(leftOverLength - payloadLength, readBuffer); } } @@ -680,6 +691,8 @@ namespace SleepyDiscord { case pongOp: // only needed if ping send is implemented break; + case continueOp: + // shouldn't happen because we don't support websocket fragmentation default: std::cerr << "Unknown op code from server\n"; return;