diff --git a/src/backend/commands/session/join_session.cpp b/src/backend/commands/session/join_session.cpp new file mode 100644 index 00000000..b75a0e29 --- /dev/null +++ b/src/backend/commands/session/join_session.cpp @@ -0,0 +1,89 @@ +#include "backend/command.hpp" +#include "util/session.hpp" + +namespace big +{ + class switch_session : command + { + std::unordered_map m_session_types = { + {eSessionType::JOIN_PUBLIC, "PUB"}, + {eSessionType::NEW_PUBLIC, "NEWPUB"}, + {eSessionType::CLOSED_CREW, "CLOSEDCREW"}, + {eSessionType::CREW, "NEWCREW"}, + {eSessionType::CLOSED_FRIENDS, "CLOSEDFRIENDS"}, + {eSessionType::FIND_FRIEND, "FRIENDS"}, + {eSessionType::SOLO, "SOLO"}, + {eSessionType::INVITE_ONLY, "INVITE"}, + {eSessionType::JOIN_CREW, "CREW"}, + {eSessionType::SC_TV, "SCTV"}, + {eSessionType::LEAVE_ONLINE, "SINGLEPLAYER"}, + }; + + using command::command; + + std::string valid_args(bool was_session_string = false) + { + std::string valid_args; + if (was_session_string) + { + for (const auto& session_type_string : m_session_types | std::ranges::views::values) + { + if (!empty(valid_args)) + { + valid_args += ", "; + } + valid_args += session_type_string; + } + + return valid_args; + } + + for (const auto& session_type_id : m_session_types | std::ranges::views::keys) + { + if (!empty(valid_args)) + { + valid_args += ", "; + } + valid_args += std::to_string(static_cast(session_type_id)); + } + + return valid_args; + } + + virtual std::optional parse_args(const std::vector& args, const std::shared_ptr ctx) override + { + command_arguments result(1); + auto sessionType = static_cast(std::atoi(args[0].c_str())); + if (m_session_types.find(sessionType) == m_session_types.end()) + { + ctx->report_error(std::format("Invalid session type ID given \"{}\", valid inputs are [{}].", args[0], valid_args())); + + return std::nullopt; + } + + if (sessionType == eSessionType::JOIN_PUBLIC && args[0] != "0") + { + const auto it = std::find_if(m_session_types.begin(), m_session_types.end(), [&args](const std::pair& t) -> bool { + return t.second == args[0]; + }); + if (it == m_session_types.end()) + { + ctx->report_error(std::format("Unknown session type \"{}\", valid inputs are [{}].", args[0], valid_args(true))); + + return std::nullopt; + } + + sessionType = it->first; + } + + result.push(sessionType); + return result; + } + + virtual void execute(const command_arguments& args, const std::shared_ptr ctx) override + { + session::join_type(args.shift()); + } + }; + switch_session g_switch_session("joinsession", "Join Session", "Join a specific session type.", 1); +} \ No newline at end of file diff --git a/src/backend/commands/session/wipe_session.cpp b/src/backend/commands/session/wipe_session.cpp index 343e86c8..112dc715 100644 --- a/src/backend/commands/session/wipe_session.cpp +++ b/src/backend/commands/session/wipe_session.cpp @@ -1,4 +1,4 @@ -#include "backend/player_command.hpp" +#include "backend/command.hpp" #include "network/CNetworkPlayerMgr.hpp" #include "pointers.hpp" #include "services/players/player_service.hpp" diff --git a/src/file_manager.cpp b/src/file_manager.cpp index e9e03cf0..540e5c8d 100644 --- a/src/file_manager.cpp +++ b/src/file_manager.cpp @@ -18,7 +18,9 @@ namespace big file file_manager::get_project_file(std::filesystem::path file_path) { if (file_path.is_absolute()) - throw std::exception("Project files are relative to the BaseDir, don't use absolute paths!"); + throw std::invalid_argument("Project files are relative to the BaseDir, don't use absolute paths!"); + if (file_path.string().contains("..")) + throw std::invalid_argument("Relative path traversal is not allowed, refrain from using \"..\" in file paths."); return file_manager::ensure_file_can_be_created(m_base_dir / file_path); } @@ -26,7 +28,9 @@ namespace big folder file_manager::get_project_folder(std::filesystem::path folder_path) { if (folder_path.is_absolute()) - throw std::exception("Project folders are relative to the BaseDir, don't use absolute paths!"); + throw std::invalid_argument("Project folders are relative to the BaseDir, don't use absolute paths!"); + if (folder_path.string().contains("..")) + throw std::invalid_argument("Relative path traversal is not allowed, refrain from using \"..\" in folder paths."); return file_manager::ensure_folder_exists(m_base_dir / folder_path); } diff --git a/src/file_manager/folder.cpp b/src/file_manager/folder.cpp index e0adf19d..d21557fa 100644 --- a/src/file_manager/folder.cpp +++ b/src/file_manager/folder.cpp @@ -12,7 +12,9 @@ namespace big file folder::get_file(std::filesystem::path file_path) const { if (file_path.is_absolute()) - throw std::exception("folder#get_file requires a relative path."); + throw std::invalid_argument("folder#get_file requires a relative path."); + if (file_path.string().contains("..")) + throw std::invalid_argument("Relative path traversal is not allowed, refrain from using \"..\" in file paths."); return file(m_folder_path / file_path); }