Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #9759 from Techjar/netplay-sanitize-gci
NetPlay: Check file names when receiving GCI folder
  • Loading branch information
JosJuice committed May 31, 2021
2 parents c648058 + 1377f31 commit c404452
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
18 changes: 15 additions & 3 deletions Source/Core/Common/NandPaths.cpp
Expand Up @@ -95,6 +95,13 @@ bool IsTitlePath(const std::string& path, std::optional<FromWhichRoot> from, u64
return true;
}

static bool IsIllegalCharacter(char c)
{
static const std::unordered_set<char> illegal_chars = {'\"', '*', '/', ':', '<',
'>', '?', '\\', '|', '\x7f'};
return (c >= 0 && c <= 0x1F) || illegal_chars.find(c) != illegal_chars.end();
}

std::string EscapeFileName(const std::string& filename)
{
// Prevent paths from containing special names like ., .., ..., ...., and so on
Expand All @@ -105,13 +112,11 @@ std::string EscapeFileName(const std::string& filename)
std::string filename_with_escaped_double_underscores = ReplaceAll(filename, "__", "__5f____5f__");

// Escape all other characters that need to be escaped
static const std::unordered_set<char> chars_to_replace = {'\"', '*', '/', ':', '<',
'>', '?', '\\', '|', '\x7f'};
std::string result;
result.reserve(filename_with_escaped_double_underscores.size());
for (char c : filename_with_escaped_double_underscores)
{
if ((c >= 0 && c <= 0x1F) || chars_to_replace.find(c) != chars_to_replace.end())
if (IsIllegalCharacter(c))
result.append(fmt::format("__{:02x}__", c));
else
result.push_back(c);
Expand Down Expand Up @@ -151,4 +156,11 @@ std::string UnescapeFileName(const std::string& filename)

return result;
}

bool IsFileNameSafe(const std::string_view filename)
{
return !filename.empty() &&
!std::all_of(filename.begin(), filename.end(), [](char c) { return c == '.'; }) &&
std::none_of(filename.begin(), filename.end(), IsIllegalCharacter);
}
} // namespace Common
2 changes: 2 additions & 0 deletions Source/Core/Common/NandPaths.h
Expand Up @@ -43,4 +43,6 @@ std::string EscapeFileName(const std::string& filename);
std::string EscapePath(const std::string& path);
// Reverses escaping done by EscapeFileName
std::string UnescapeFileName(const std::string& filename);
// Tests for a file name being "safe" as per the escaping defined in EscapeFileName
bool IsFileNameSafe(const std::string_view filename);
} // namespace Common
3 changes: 2 additions & 1 deletion Source/Core/Core/NetPlayClient.cpp
Expand Up @@ -905,7 +905,8 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
std::string file_name;
packet >> file_name;

if (!DecompressPacketIntoFile(packet, path + DIR_SEP + file_name))
if (!Common::IsFileNameSafe(file_name) ||
!DecompressPacketIntoFile(packet, path + DIR_SEP + file_name))
{
SyncSaveDataResponse(false);
return 0;
Expand Down

0 comments on commit c404452

Please sign in to comment.