From 8d3c1adf05cf15faa1679babc5bf6217f727644e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 17 Aug 2022 09:55:47 +0200 Subject: [PATCH] - do not use POSIX directory functions in common code. For Windows these need to redirect to Unicode system functions to properly handle paths not representable in 8 bit encodings. --- src/common/console/c_enginecmds.cpp | 11 ++++---- src/common/platform/posix/cocoa/i_system.mm | 17 +++++++++++- src/common/platform/posix/i_system.h | 2 ++ src/common/platform/posix/sdl/i_system.cpp | 17 +++++++++++- src/common/platform/win32/i_system.cpp | 19 +++++++++++++ src/common/platform/win32/i_system.h | 2 ++ src/common/utility/findfile.cpp | 30 ++++++++++----------- 7 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/common/console/c_enginecmds.cpp b/src/common/console/c_enginecmds.cpp index d2d279619..13593cb32 100644 --- a/src/common/console/c_enginecmds.cpp +++ b/src/common/console/c_enginecmds.cpp @@ -53,6 +53,7 @@ #include "findfile.h" #include "md5.h" #include "i_specialpaths.h" +#include "i_system.h" extern FILE* Logfile; @@ -178,12 +179,12 @@ UNSAFE_CCMD (crashout) UNSAFE_CCMD (dir) { FString dir, path; - char curdir[256]; const char *match; findstate_t c_file; void *file; - if (!getcwd (curdir, countof(curdir))) + FString curdir = I_GetCWD(); + if (curdir.IsEmpty()) { Printf ("Current path too long\n"); return; @@ -192,7 +193,7 @@ UNSAFE_CCMD (dir) if (argv.argc() > 1) { path = NicePath(argv[1]); - if (chdir(path)) + if (!I_ChDir(path)) { match = path; dir = ExtractFilePath(path); @@ -208,7 +209,7 @@ UNSAFE_CCMD (dir) { match = "*"; } - if (chdir (dir)) + if (!I_ChDir(dir)) { Printf ("%s not found\n", dir.GetChars()); return; @@ -245,7 +246,7 @@ UNSAFE_CCMD (dir) I_FindClose (file); } - chdir (curdir); + I_ChDir(curdir); } //========================================================================== diff --git a/src/common/platform/posix/cocoa/i_system.mm b/src/common/platform/posix/cocoa/i_system.mm index e67ffe0a0..58617cd81 100644 --- a/src/common/platform/posix/cocoa/i_system.mm +++ b/src/common/platform/posix/cocoa/i_system.mm @@ -171,9 +171,24 @@ unsigned int I_MakeRNGSeed() return static_cast(arc4random()); } +FString I_GetCWD() +{ + char curdir[PATH_MAX]; + if (!getcwd(curdir, countof(curdir))) + { + return ""; + } + return curdir; +} + +bool I_ChDir(const char* path) +{ + return chdir(path) == 0; +} + void I_OpenShellFolder(const char* folder) { - char curdir[256]; + char curdir[PATH_MAX]; if (!getcwd (curdir, countof(curdir))) { Printf ("Current path too long\n"); diff --git a/src/common/platform/posix/i_system.h b/src/common/platform/posix/i_system.h index fdba79add..ae3faa80b 100644 --- a/src/common/platform/posix/i_system.h +++ b/src/common/platform/posix/i_system.h @@ -69,6 +69,8 @@ inline int I_GetNumaNodeCount() { return 1; } inline int I_GetNumaNodeThreadCount(int numaNode) { return std::max(std::thread::hardware_concurrency(), 1); } inline void I_SetThreadNumaNode(std::thread &thread, int numaNode) { } +FString I_GetCWD(); +bool I_ChDir(const char* path); void I_OpenShellFolder(const char*); #endif diff --git a/src/common/platform/posix/sdl/i_system.cpp b/src/common/platform/posix/sdl/i_system.cpp index 0697d1140..53fc55836 100644 --- a/src/common/platform/posix/sdl/i_system.cpp +++ b/src/common/platform/posix/sdl/i_system.cpp @@ -410,6 +410,21 @@ FString I_GetFromClipboard (bool use_primary_selection) return ""; } +FString I_GetCWD() +{ + char curdir[PATH_MAX]; + if (!getcwd(curdir, countof(curdir))) + { + return ""; + } + return curdir; +} + +bool I_ChDir(const char* path) +{ + return chdir(path) == 0; +} + // Return a random seed, preferably one with lots of entropy. unsigned int I_MakeRNGSeed() { @@ -434,7 +449,7 @@ unsigned int I_MakeRNGSeed() void I_OpenShellFolder(const char* folder) { - char curdir[256]; + char curdir[PATH_MAX]; if (!getcwd (curdir, countof(curdir))) { Printf ("Current path too long\n"); diff --git a/src/common/platform/win32/i_system.cpp b/src/common/platform/win32/i_system.cpp index cc31739a5..1005bd9d1 100644 --- a/src/common/platform/win32/i_system.cpp +++ b/src/common/platform/win32/i_system.cpp @@ -961,6 +961,25 @@ void I_SetThreadNumaNode(std::thread &thread, int numaNode) } } +FString I_GetCWD() +{ + auto len = GetCurrentDirectoryW(0, nullptr); + TArray curdir(len + 1, true); + if (!GetCurrentDirectoryW(len + 1, curdir.Data())) + { + return ""; + } + FString returnv(curdir.Data()); + FixPathSeperator(returnv); + return returnv; +} + +bool I_ChDir(const char* path) +{ + return SetCurrentDirectoryW(WideString(path).c_str()); +} + + void I_OpenShellFolder(const char* infolder) { auto len = GetCurrentDirectoryW(0, nullptr); diff --git a/src/common/platform/win32/i_system.h b/src/common/platform/win32/i_system.h index 441a0d3fd..cebbfde8f 100644 --- a/src/common/platform/win32/i_system.h +++ b/src/common/platform/win32/i_system.h @@ -80,5 +80,7 @@ int I_GetNumaNodeThreadCount(int numaNode); void I_SetThreadNumaNode(std::thread &thread, int numaNode); void I_OpenShellFolder(const char*); +FString I_GetCWD(); +bool I_ChDir(const char* path); #endif diff --git a/src/common/utility/findfile.cpp b/src/common/utility/findfile.cpp index bdfa865a8..0da6a97ff 100644 --- a/src/common/utility/findfile.cpp +++ b/src/common/utility/findfile.cpp @@ -37,6 +37,7 @@ #include "cmdlib.h" #include "printf.h" #include "configfile.h" +#include "i_system.h" #ifndef _WIN32 @@ -369,9 +370,8 @@ void D_AddConfigFiles(TArray& wadfiles, const char* section, const char void D_AddDirectory(TArray& wadfiles, const char* dir, const char *filespec, FConfigFile* config) { - char curdir[ZPATH_MAX]; - - if (getcwd(curdir, ZPATH_MAX)) + FString curdir = I_GetCWD(); + if (curdir.IsNotEmpty()) { char skindir[ZPATH_MAX]; findstate_t findstate; @@ -387,7 +387,7 @@ void D_AddDirectory(TArray& wadfiles, const char* dir, const char *file skindir[--stuffstart] = 0; } - if (!chdir(skindir)) + if (I_ChDir(skindir)) { skindir[stuffstart++] = '/'; if ((handle = I_FindFirst(filespec, &findstate)) != (void*)-1) @@ -403,7 +403,7 @@ void D_AddDirectory(TArray& wadfiles, const char* dir, const char *file I_FindClose(handle); } } - chdir(curdir); + I_ChDir(curdir); } } @@ -417,27 +417,27 @@ void D_AddDirectory(TArray& wadfiles, const char* dir, const char *file // //========================================================================== +static FString BFSwad; // outside the function to evade C++'s insane rules for constructing static variables inside functions. + const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinprogdir, FConfigFile* config) { - static char wad[ZPATH_MAX]; - if (file == nullptr || *file == '\0') { return nullptr; } if (lookfirstinprogdir) { - mysnprintf(wad, countof(wad), "%s%s%s", progdir.GetChars(), progdir.Back() == '/' ? "" : "/", file); - if (DirEntryExists(wad)) + BFSwad.Format("%s%s%s", progdir.GetChars(), progdir.Back() == '/' ? "" : "/", file); + if (DirEntryExists(BFSwad)) { - return wad; + return BFSwad.GetChars(); } } if (DirEntryExists(file)) { - mysnprintf(wad, countof(wad), "%s", file); - return wad; + BFSwad.Format("%s", file); + return BFSwad.GetChars(); } if (config != nullptr && config->SetSection("FileSearch.Directories")) @@ -454,10 +454,10 @@ const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinpr dir = NicePath(value); if (dir.IsNotEmpty()) { - mysnprintf(wad, countof(wad), "%s%s%s", dir.GetChars(), dir.Back() == '/' ? "" : "/", file); - if (DirEntryExists(wad)) + BFSwad.Format("%s%s%s", dir.GetChars(), dir.Back() == '/' ? "" : "/", file); + if (DirEntryExists(BFSwad)) { - return wad; + return BFSwad.GetChars(); } } }