Skip to content

Commit

Permalink
Fix crashes with fs::path on some edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf109909 committed Oct 5, 2024
1 parent c1faa4b commit 3827408
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 43 deletions.
9 changes: 5 additions & 4 deletions primedev/client/languagehooks.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
#include "core/tier0.h"

#include "core/filesystem/filesystem.h"
#include <filesystem>
#include <regex>

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<std::string> file_list(fs::path dir, std::regex ext_pattern)
{
std::vector<std::string> result;

if (!fs::exists(dir) || !fs::is_directory(dir))
return result;

Expand All @@ -40,7 +41,7 @@ std::vector<std::string> 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";
Expand Down
40 changes: 2 additions & 38 deletions primedev/core/filesystem/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down
37 changes: 37 additions & 0 deletions primedev/core/filesystem/filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
2 changes: 1 addition & 1 deletion thirdparty/silver-bun

0 comments on commit 3827408

Please sign in to comment.