From 3827408ce7a0c657484255b1aba1b655d4169520 Mon Sep 17 00:00:00 2001 From: wolf109909 <84360921+wolf109909@users.noreply.github.com> Date: Sat, 5 Oct 2024 21:41:11 +0800 Subject: [PATCH] Fix crashes with fs::path on some edge cases --- primedev/client/languagehooks.cpp | 9 +++--- primedev/core/filesystem/filesystem.cpp | 40 ++----------------------- primedev/core/filesystem/filesystem.h | 37 +++++++++++++++++++++++ thirdparty/silver-bun | 2 +- 4 files changed, 45 insertions(+), 43 deletions(-) diff --git a/primedev/client/languagehooks.cpp b/primedev/client/languagehooks.cpp index 80d3c31d9..9c957eb2d 100644 --- a/primedev/client/languagehooks.cpp +++ b/primedev/client/languagehooks.cpp @@ -1,5 +1,5 @@ #include "core/tier0.h" - +#include "core/filesystem/filesystem.h" #include #include @@ -7,18 +7,19 @@ namespace fs = std::filesystem; typedef LANGID (*Tier0_DetectDefaultLanguageType)(); + bool CheckLangAudioExists(char* lang) { std::string path {"r2\\sound\\general_"}; path += lang; path += ".mstr"; - return fs::exists(path); + return fs::exists(SanitizeEncodings(path.c_str())); } std::vector file_list(fs::path dir, std::regex ext_pattern) { std::vector result; - + if (!fs::exists(dir) || !fs::is_directory(dir)) return result; @@ -40,7 +41,7 @@ std::vector file_list(fs::path dir, std::regex ext_pattern) std::string GetAnyInstalledAudioLanguage() { - for (const auto& lang : file_list("r2\\sound\\", std::regex(".*?general_([a-z]+)_patch_1\\.mstr"))) + for (const auto& lang : file_list(SanitizeEncodings("r2\\sound\\"), std::regex(".*?general_([a-z]+)_patch_1\\.mstr"))) if (lang != "general" && lang != "" && lang != "stream") return lang; return "NO LANGUAGE DETECTED"; diff --git a/primedev/core/filesystem/filesystem.cpp b/primedev/core/filesystem/filesystem.cpp index 34ab16d48..bb3abbf7d 100644 --- a/primedev/core/filesystem/filesystem.cpp +++ b/primedev/core/filesystem/filesystem.cpp @@ -83,11 +83,11 @@ bool TryReplaceFile(const char* pPath, bool shouldCompile) return false; if (shouldCompile) - g_pModManager->CompileAssetsForFile(pPath); + g_pModManager->CompileAssetsForFile(SanitizeEncodings(pPath).c_str()); // idk how efficient the lexically normal check is // can't just set all /s in path to \, since some paths aren't in writeable memory - auto file = g_pModManager->m_ModFiles.find(g_pModManager->NormaliseModFilePath(fs::path(pPath))); + auto file = g_pModManager->m_ModFiles.find(g_pModManager->NormaliseModFilePath(fs::path(SanitizeEncodings(pPath)))); if (file != g_pModManager->m_ModFiles.end()) { SetNewModSearchPaths(file->second.m_pOwningMod); @@ -97,43 +97,7 @@ bool TryReplaceFile(const char* pPath, bool shouldCompile) return false; } -std::string ConvertWideToANSI(const std::wstring& wstr) -{ - int count = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL); - std::string str(count, 0); - WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL); - return str; -} -std::wstring ConvertAnsiToWide(const std::string& str) -{ - int count = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), NULL, 0); - std::wstring wstr(count, 0); - MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), &wstr[0], count); - return wstr; -} - -std::string ConvertWideToUtf8(const std::wstring& wstr) -{ - int count = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL); - std::string str(count, 0); - WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL); - return str; -} - -std::wstring ConvertUtf8ToWide(const std::string& str) -{ - int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0); - std::wstring wstr(count, 0); - MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count); - return wstr; -} - -std::string SanitizeEncodings(const char* buf) -{ - std::wstring ws = ConvertAnsiToWide(buf); - return ConvertWideToUtf8(ws); -} // force modded files to be read from mods, not cache static bool(__fastcall* o_pReadFromCache)(IFileSystem* filesystem, char* pPath, void* result) = nullptr; static bool __fastcall h_ReadFromCache(IFileSystem* filesystem, char* pPath, void* result) diff --git a/primedev/core/filesystem/filesystem.h b/primedev/core/filesystem/filesystem.h index 2c592b3f6..3676c4f65 100644 --- a/primedev/core/filesystem/filesystem.h +++ b/primedev/core/filesystem/filesystem.h @@ -51,3 +51,40 @@ extern IFileSystem* g_pFilesystem; std::string ReadVPKFile(const char* path); std::string ReadVPKOriginalFile(const char* path); +static std::string ConvertWideToANSI(const std::wstring& wstr) +{ + int count = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL); + std::string str(count, 0); + WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL); + return str; +} + +static std::wstring ConvertAnsiToWide(const std::string& str) +{ + int count = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), NULL, 0); + std::wstring wstr(count, 0); + MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), &wstr[0], count); + return wstr; +} + +static std::string ConvertWideToUtf8(const std::wstring& wstr) +{ + int count = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL); + std::string str(count, 0); + WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL); + return str; +} + +static std::wstring ConvertUtf8ToWide(const std::string& str) +{ + int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0); + std::wstring wstr(count, 0); + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count); + return wstr; +} + +static std::string SanitizeEncodings(const char* buf) +{ + std::wstring ws = ConvertAnsiToWide(buf); + return ConvertWideToUtf8(ws); +} \ No newline at end of file diff --git a/thirdparty/silver-bun b/thirdparty/silver-bun index 499319628..e303804b6 160000 --- a/thirdparty/silver-bun +++ b/thirdparty/silver-bun @@ -1 +1 @@ -Subproject commit 499319628e1b51234572e8d4008fd6e991c7566f +Subproject commit e303804b6fd84120c30da7813269638ec8404fcf