diff --git a/Source/Core/Core/Slippi/SlippiNetplay.cpp b/Source/Core/Core/Slippi/SlippiNetplay.cpp index c7f7f49a17..aee1f36fb8 100644 --- a/Source/Core/Core/Slippi/SlippiNetplay.cpp +++ b/Source/Core/Core/Slippi/SlippiNetplay.cpp @@ -125,15 +125,21 @@ SlippiNetplayClient::SlippiNetplayClient(bool isDecider) // called from ---NETPLAY--- thread unsigned int SlippiNetplayClient::OnData(sf::Packet& packet) { - NetPlay::MessageId mid; - packet >> mid; + NetPlay::MessageId mid = 0; + if (!(packet >> mid)) { + ERROR_LOG(SLIPPI_ONLINE, "Received empty netplay packet"); + return 0; + } switch (mid) { case NetPlay::NP_MSG_SLIPPI_PAD: { int32_t frame; - packet >> frame; + if (!(packet >> frame)) { + ERROR_LOG(SLIPPI_ONLINE, "Netplay packet too small to read frame count"); + break; + } // Pad received, try to guess what our local time was when the frame was sent by our opponent // before we initialized @@ -175,6 +181,13 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet) int32_t headFrame = remotePadQueue.empty() ? 0 : remotePadQueue.front()->frame; int inputsToCopy = frame - headFrame; + + // Check that the packet actually contains the data it claims to + if ((5 + inputsToCopy * SLIPPI_PAD_DATA_SIZE) > (int)packet.getDataSize()) { + ERROR_LOG(SLIPPI_ONLINE, "Netplay packet too small to read pad buffer"); + break; + } + for (int i = inputsToCopy - 1; i >= 0; i--) { auto pad = std::make_unique(frame - i, &packetData[5 + i * SLIPPI_PAD_DATA_SIZE]); @@ -201,7 +214,10 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet) // Store last frame acked int32_t frame; - packet >> frame; + if (!(packet >> frame)) { + ERROR_LOG(SLIPPI_ONLINE, "Ack packet too small to read frame"); + break; + } lastFrameAcked = frame > lastFrameAcked ? frame : lastFrameAcked; @@ -257,7 +273,7 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet) break; default: - PanicAlertT("Unknown message received with id : %d", mid); + WARN_LOG(SLIPPI_ONLINE, "Unknown message received with id : %d", mid); break; }