From 8d4cd7d8e1101e3c7a2241ecb2ad4d9598899f67 Mon Sep 17 00:00:00 2001 From: Nikhil Narayana Date: Mon, 30 May 2022 01:06:56 -0700 Subject: [PATCH] pull in project-slippi/Ishiiruka/commit/11b0f4de469b3d9c1aa8424bc37b70ade4dc5718 and project-slippi/Ishiiruka/commit/df5e6190bc5162a5594cbc4b7b914c339c2feb14 --- Source/Core/Core/Slippi/SlippiNetplay.cpp | 131 +++++++++++++++++----- Source/Core/Core/Slippi/SlippiNetplay.h | 3 +- 2 files changed, 108 insertions(+), 26 deletions(-) diff --git a/Source/Core/Core/Slippi/SlippiNetplay.cpp b/Source/Core/Core/Slippi/SlippiNetplay.cpp index 0329dd732d..5de524e298 100644 --- a/Source/Core/Core/Slippi/SlippiNetplay.cpp +++ b/Source/Core/Core/Slippi/SlippiNetplay.cpp @@ -388,18 +388,26 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer) case NetPlay::NP_MSG_SLIPPI_MATCH_SELECTIONS: { auto s = readSelectionsFromPacket(packet); - INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Received selections from opponent with player idx {}", - s->playerIdx); - u8 idx = PlayerIdxFromPort(s->playerIdx); - matchInfo.remotePlayerSelections[idx].Merge(*s); + if (!s->error) + { + INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Received selections from opponent with player idx {}", + s->playerIdx); + u8 idx = PlayerIdxFromPort(s->playerIdx); + if (idx >= m_remotePlayerCount) + { + ERROR_LOG_FMT(SLIPPI_ONLINE, "Got match selection packet with invalid player idx {}", idx); + break; + } + matchInfo.remotePlayerSelections[idx].Merge(*s); - // This might be a good place to reset some logic? Game can't start until we receive this msg - // so this should ensure that everything is initialized before the game starts - hasGameStarted = false; + // This might be a good place to reset some logic? Game can't start until we receive this msg + // so this should ensure that everything is initialized before the game starts + hasGameStarted = false; - // Reset remote pad queue such that next inputs that we get are not compared to inputs from last - // game - remotePadQueue[idx].clear(); + // Reset remote pad queue such that next inputs that we get are not compared to inputs from + // last game + remotePadQueue[idx].clear(); + } } break; @@ -418,8 +426,11 @@ unsigned int SlippiNetplayClient::OnData(sf::Packet& packet, ENetPeer* peer) remoteSentChatMessageId = 0; break; } - // set message id to netplay instance - remoteChatMessageSelection = std::move(playerSelection); + if (!playerSelection->error) + { + // set message id to netplay instance + remoteChatMessageSelection = std::move(playerSelection); + } } break; @@ -461,8 +472,49 @@ SlippiNetplayClient::ReadChatMessageFromPacket(sf::Packet& packet) { auto s = std::make_unique(); - packet >> s->messageId; - packet >> s->playerIdx; + if (!(packet >> s->messageId)) + { + ERROR_LOG(SLIPPI_ONLINE, "Chat packet too small to read message ID"); + s->error = true; + return std::move(s); + } + if (!(packet >> s->playerIdx)) + { + ERROR_LOG(SLIPPI_ONLINE, "Chat packet too small to read player index"); + s->error = true; + return std::move(s); + } + + switch (s->messageId) + { + // Only these 16 message IDs are allowed + case 136: + case 129: + case 130: + case 132: + case 34: + case 40: + case 33: + case 36: + case 72: + case 66: + case 68: + case 65: + case 24: + case 18: + case 20: + case 17: + { + // Good message ID. Do nothing + break; + } + default: + { + ERROR_LOG_FMT(SLIPPI_ONLINE, "Received invalid chat message index: {}", s->messageId); + s->error = true; + break; + } + } return std::move(s); } @@ -472,17 +524,46 @@ SlippiNetplayClient::readSelectionsFromPacket(sf::Packet& packet) { auto s = std::make_unique(); - packet >> s->characterId; - packet >> s->characterColor; - packet >> s->isCharacterSelected; - - packet >> s->playerIdx; - - packet >> s->stageId; - packet >> s->isStageSelected; - packet >> s->rngOffset; - - packet >> s->teamId; + if (!(packet >> s->characterId)) + { + ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + s->error = true; + } + if (!(packet >> s->characterColor)) + { + ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + s->error = true; + } + if (!(packet >> s->isCharacterSelected)) + { + ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + s->error = true; + } + if (!(packet >> s->playerIdx)) + { + ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + s->error = true; + } + if (!(packet >> s->stageId)) + { + ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + s->error = true; + } + if (!(packet >> s->isStageSelected)) + { + ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + s->error = true; + } + if (!(packet >> s->rngOffset)) + { + ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + s->error = true; + } + if (!(packet >> s->teamId)) + { + ERROR_LOG(SLIPPI_ONLINE, "Received invalid player selection"); + s->error = true; + } return std::move(s); } diff --git a/Source/Core/Core/Slippi/SlippiNetplay.h b/Source/Core/Core/Slippi/SlippiNetplay.h index f197d50df3..445b649bb5 100644 --- a/Source/Core/Core/Slippi/SlippiNetplay.h +++ b/Source/Core/Core/Slippi/SlippiNetplay.h @@ -54,7 +54,8 @@ public: u32 rngOffset{}; - int messageId{}; + int messageId = 0; + bool error = false; void Merge(SlippiPlayerSelections& s) {