diff --git a/Core/GameEngine/Source/Common/System/ArchiveFile.cpp b/Core/GameEngine/Source/Common/System/ArchiveFile.cpp index 1f982b65a1d..8fcf7bbb3d3 100644 --- a/Core/GameEngine/Source/Common/System/ArchiveFile.cpp +++ b/Core/GameEngine/Source/Common/System/ArchiveFile.cpp @@ -32,6 +32,7 @@ #include "Common/ArchiveFileSystem.h" #include "Common/file.h" #include "Common/PerfTimer.h" +#include "Lib/PathUtil.h" // checks to see if str matches searchString. Search string is done in the @@ -81,6 +82,14 @@ static Bool SearchStringMatches(AsciiString str, AsciiString searchString) return FALSE; } +static void appendNativePathSeparator(AsciiString &path) +{ + if (!path.isEmpty() && !path.endsWith("\\") && !path.endsWith("/")) + { + path.concat(getNativePathSeparator()); + } +} + ArchiveFile::~ArchiveFile() { if (m_file != nullptr) { @@ -157,9 +166,9 @@ void ArchiveFile::getFileListInDirectory(const DetailedArchivedDirectoryInfo *di const DetailedArchivedDirectoryInfo *tempDirInfo = &(diriter->second); AsciiString tempdirname; tempdirname = currentDirectory; - if ((!tempdirname.isEmpty()) && (!tempdirname.endsWith("\\"))) { - tempdirname.concat('\\'); - } + // TheSuperHackers @bugfix bobtista 14/08/2026 Keep archive listings native when a caller + // supplies a path ending in '/', rather than appending '\\' and creating a mixed path. + appendNativePathSeparator(tempdirname); tempdirname.concat(tempDirInfo->m_directoryName); getFileListInDirectory(tempDirInfo, tempdirname, searchName, filenameList, searchSubdirectories); diriter++; @@ -170,9 +179,7 @@ void ArchiveFile::getFileListInDirectory(const DetailedArchivedDirectoryInfo *di if (SearchStringMatches(fileiter->second.m_filename, searchName)) { AsciiString tempfilename; tempfilename = currentDirectory; - if ((!tempfilename.isEmpty()) && (!tempfilename.endsWith("\\"))) { - tempfilename.concat('\\'); - } + appendNativePathSeparator(tempfilename); tempfilename.concat(fileiter->second.m_filename); if (filenameList.find(tempfilename) == filenameList.end()) { // only insert into the list if its not already in there. diff --git a/Core/Libraries/Include/Lib/PathUtil.h b/Core/Libraries/Include/Lib/PathUtil.h index cf1ce769d91..eddade82485 100644 --- a/Core/Libraries/Include/Lib/PathUtil.h +++ b/Core/Libraries/Include/Lib/PathUtil.h @@ -23,6 +23,29 @@ #include "BaseType.h" #include +inline char getNativePathSeparator() +{ +#ifdef _WIN32 + return '\\'; +#else + return '/'; +#endif +} + +inline const char* getLastPathSeparator(const char* path) +{ + const char* forward = strrchr(path, '/'); + const char* backward = strrchr(path, '\\'); + return !forward ? backward : (!backward || forward > backward ? forward : backward); +} + +inline const wchar_t* getLastPathSeparator(const wchar_t* path) +{ + const wchar_t* forward = wcsrchr(path, L'/'); + const wchar_t* backward = wcsrchr(path, L'\\'); + return !forward ? backward : (!backward || forward > backward ? forward : backward); +} + inline const char* getExtension(const char* path) { const char* lastDot = strrchr(path, '.'); @@ -32,7 +55,7 @@ inline const char* getExtension(const char* path) return nullptr; } - const char* lastSeparator = maxPtr(strrchr(path, '/'), strrchr(path, '\\')); + const char* lastSeparator = getLastPathSeparator(path); // Check if the dot is contained in the filename if (lastSeparator && lastDot < lastSeparator) @@ -52,7 +75,7 @@ inline const wchar_t* getExtension(const wchar_t* path) return nullptr; } - const wchar_t* lastSeparator = maxPtr(wcsrchr(path, L'/'), wcsrchr(path, L'\\')); + const wchar_t* lastSeparator = getLastPathSeparator(path); // Check if the dot is contained in the filename if (lastSeparator && lastDot < lastSeparator)