From 2a55829d5ae61c647cd66c47d1e143e66aefba98 Mon Sep 17 00:00:00 2001 From: Edo Date: Fri, 7 Apr 2023 19:38:23 +0200 Subject: [PATCH] [IO]: Refactor GSC funcs (#910) --- src/Components/Modules/Bots.cpp | 3 + src/Components/Modules/GSC/IO.cpp | 126 ++++++++++++++++-------------- src/Components/Modules/GSC/IO.hpp | 2 + 3 files changed, 74 insertions(+), 57 deletions(-) diff --git a/src/Components/Modules/Bots.cpp b/src/Components/Modules/Bots.cpp index 5f4dae7d..a3962991 100644 --- a/src/Components/Modules/Bots.cpp +++ b/src/Components/Modules/Bots.cpp @@ -269,6 +269,9 @@ namespace Components g_botai[entref.entnum].right = static_cast(rightInt); g_botai[entref.entnum].active = true; }); + + GSC::Script::AddMethod("SetPing", []([[maybe_unused]] const Game::scr_entref_t entref) + {}); } void Bots::BotAiAction(Game::client_t* cl) diff --git a/src/Components/Modules/GSC/IO.cpp b/src/Components/Modules/GSC/IO.cpp index af5ac692..fd9176a2 100644 --- a/src/Components/Modules/GSC/IO.cpp +++ b/src/Components/Modules/GSC/IO.cpp @@ -10,19 +10,29 @@ namespace Components::GSC std::filesystem::path IO::Path; + bool IO::ValidatePath(const char* function, const char* path) + { + for (std::size_t i = 0; i < std::extent_v; ++i) + { + if (std::strstr(path, ForbiddenStrings[i]) != nullptr) + { + Logger::PrintError(Game::CON_CHANNEL_PARSERSCRIPT, "{}: directory traversal is not allowed!\n", function); + return false; + } + } + + return true; + } + void IO::GScr_OpenFile() { const auto* filepath = Game::Scr_GetString(0); const auto* mode = Game::Scr_GetString(1); - for (std::size_t i = 0; i < std::extent_v; ++i) + if (!ValidatePath("OpenFile", filepath)) { - if (std::strstr(filepath, ForbiddenStrings[i]) != nullptr) - { - Logger::PrintError(Game::CON_CHANNEL_PARSERSCRIPT, "OpenFile: directory traversal is not allowed!\n"); - Game::Scr_AddInt(-1); - return; - } + Game::Scr_AddInt(-1); + return; } if (mode != "read"s) @@ -97,27 +107,11 @@ namespace Components::GSC const auto* text = Game::Scr_GetString(1); const auto* mode = Game::Scr_GetString(2); - if (!filepath) + if (!ValidatePath("FileWrite", filepath)) { - Game::Scr_ParamError(0, "FileWrite: filepath is not defined!"); return; } - if (!text || !mode) - { - Game::Scr_Error("FileWrite: Illegal parameters!"); - return; - } - - for (std::size_t i = 0; i < std::extent_v; ++i) - { - if (std::strstr(filepath, ForbiddenStrings[i]) != nullptr) - { - Logger::PrintError(Game::CON_CHANNEL_PARSERSCRIPT, "FileWrite: directory traversal is not allowed!\n"); - return; - } - } - if (mode != "append"s && mode != "write"s) { Logger::Warning(Game::CON_CHANNEL_PARSERSCRIPT, "FileWrite: mode not defined or was wrong, defaulting to 'write'\n"); @@ -132,21 +126,11 @@ namespace Components::GSC Script::AddFunction("FileRead", [] // gsc: FileRead() { const auto* filepath = Game::Scr_GetString(0); - if (!filepath) + if (!ValidatePath("FileRead", filepath)) { - Game::Scr_ParamError(0, "FileRead: filepath is not defined!"); return; } - for (std::size_t i = 0; i < std::extent_v; ++i) - { - if (std::strstr(filepath, ForbiddenStrings[i]) != nullptr) - { - Logger::PrintError(Game::CON_CHANNEL_PARSERSCRIPT, "FileRead: directory traversal is not allowed!\n"); - return; - } - } - const auto scriptData = Path / "scriptdata"s / filepath; std::string file; @@ -163,21 +147,11 @@ namespace Components::GSC Script::AddFunction("FileExists", [] // gsc: FileExists() { const auto* filepath = Game::Scr_GetString(0); - if (!filepath) + if (!ValidatePath("FileExists", filepath)) { - Game::Scr_ParamError(0, "FileExists: filepath is not defined!"); return; } - for (std::size_t i = 0; i < std::extent_v; ++i) - { - if (std::strstr(filepath, ForbiddenStrings[i]) != nullptr) - { - Logger::PrintError(Game::CON_CHANNEL_PARSERSCRIPT, "FileExists: directory traversal is not allowed!\n"); - return; - } - } - const auto scriptData = Path / "scriptdata"s / filepath; Game::Scr_AddBool(Utils::IO::FileExists(scriptData.string())); }); @@ -185,25 +159,63 @@ namespace Components::GSC Script::AddFunction("FileRemove", [] // gsc: FileRemove() { const auto* filepath = Game::Scr_GetString(0); - if (!filepath) + if (!ValidatePath("FileRemove", filepath)) { - Game::Scr_ParamError(0, "FileRemove: filepath is not defined!"); return; } - for (std::size_t i = 0; i < std::extent_v; ++i) - { - if (std::strstr(filepath, ForbiddenStrings[i]) != nullptr) - { - Logger::PrintError(Game::CON_CHANNEL_PARSERSCRIPT, "FileRemove: directory traversal is not allowed!\n"); - return; - } - } - const auto scriptData = Path / "scriptdata"s / filepath; Game::Scr_AddBool(Utils::IO::RemoveFile(scriptData.string())); }); + Script::AddFunction("FileRename", [] // gsc: FileRename(, ) + { + const auto* filepath = Game::Scr_GetString(0); + const auto* destpath = Game::Scr_GetString(0); + if (!ValidatePath("FileRename", filepath) || !ValidatePath("FileRename", destpath)) + { + return; + } + + const auto from = Path / "scriptdata"s / filepath; + const auto to = Path / "scriptdata"s / destpath; + + std::error_code err; + std::filesystem::rename(from, to, err); + if (err.value()) + { + Logger::PrintError(Game::CON_CHANNEL_PARSERSCRIPT, "FileRename: failed to rename file! Error message: {}\n", err.message()); + Game::Scr_AddInt(-1); + return; + } + + Game::Scr_AddInt(1); + }); + + Script::AddFunction("FileCopy", [] // gsc: FileCopy(, ) + { + const auto* filepath = Game::Scr_GetString(0); + const auto* destpath = Game::Scr_GetString(0); + if (!ValidatePath("FileCopy", filepath) || !ValidatePath("FileCopy", destpath)) + { + return; + } + + const auto from = Path / "scriptdata"s / filepath; + const auto to = Path / "scriptdata"s / destpath; + + std::error_code err; + std::filesystem::copy(from, to, err); + if (err.value()) + { + Logger::PrintError(Game::CON_CHANNEL_PARSERSCRIPT, "FileCopy: failed to copy file! Error message: {}\n", err.message()); + Game::Scr_AddInt(-1); + return; + } + + Game::Scr_AddInt(1); + }); + Script::AddFunction("ReadStream", GScr_ReadStream); } diff --git a/src/Components/Modules/GSC/IO.hpp b/src/Components/Modules/GSC/IO.hpp index 11729c89..f77ddc65 100644 --- a/src/Components/Modules/GSC/IO.hpp +++ b/src/Components/Modules/GSC/IO.hpp @@ -14,6 +14,8 @@ namespace Components::GSC static std::filesystem::path Path; + static bool ValidatePath(const char* function, const char* path); + static void GScr_OpenFile(); static void GScr_ReadStream(); static void GScr_CloseFile();