From 6fc3470a8d3b008daac662c9df2f73284501ff30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Fri, 22 Dec 2023 21:53:31 +0100 Subject: [PATCH] Check for valid favorite skin name, add `CSkin::IsValidName` Favorite skin names were previously not escaped as intended when saving, as the variable `aNameEscaped` was unused so the original skin name was saved instead of the escaped one. Escaping is not really necessary, as skins should not contain `\` and `"` anyway and it was only possible to add such favorites through the console or config files. Instead of escaping the favorite skin names when saving, now favorite skin names are validated when they are added so no escaping is necessary. Skins names are considered valid when they have a length of 1-23 bytes and don't contain the characters `/`, `\` and `"`. --- src/game/client/components/menus_settings.cpp | 13 +++++++++---- src/game/client/skin.h | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 6327b64b5..a737b0d40 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -430,7 +430,15 @@ void CMenus::Con_AddFavoriteSkin(IConsole::IResult *pResult, void *pUserData) auto *pSelf = (CMenus *)pUserData; if(pResult->NumArguments() >= 1) { - pSelf->m_SkinFavorites.emplace(pResult->GetString(0)); + const char *pStr = pResult->GetString(0); + if(!CSkin::IsValidName(pStr)) + { + char aError[IConsole::CMDLINE_LENGTH + 64]; + str_format(aError, sizeof(aError), "Favorite skin name '%s' is not valid", pStr); + pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "menus/settings", aError); + return; + } + pSelf->m_SkinFavorites.emplace(pStr); pSelf->m_SkinFavoritesChanged = true; } } @@ -460,9 +468,6 @@ void CMenus::OnConfigSave(IConfigManager *pConfigManager) for(const auto &Entry : m_SkinFavorites) { char aBuffer[256]; - char aNameEscaped[256]; - char *pDst = aNameEscaped; - str_escape(&pDst, Entry.c_str(), aNameEscaped + std::size(aNameEscaped)); str_format(aBuffer, std::size(aBuffer), "add_favorite_skin \"%s\"", Entry.c_str()); pConfigManager->WriteLine(aBuffer); } diff --git a/src/game/client/skin.h b/src/game/client/skin.h index aed057e3c..3e197c23b 100644 --- a/src/game/client/skin.h +++ b/src/game/client/skin.h @@ -142,6 +142,23 @@ public: CSkin &operator=(CSkin &&) = default; const char *GetName() const { return m_aName; } + + static bool IsValidName(const char *pName) + { + if(pName[0] == '\0' || str_length(pName) >= (int)sizeof(CSkin("").m_aName)) + { + return false; + } + + for(int i = 0; pName[i] != '\0'; ++i) + { + if(pName[i] == '"' || pName[i] == '/' || pName[i] == '\\') + { + return false; + } + } + return true; + } }; #endif