-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
Per ValveSoftware/Source-1-Games#6868 loading packed files from BSPs (& VPKs!) has some casing issue that popped up recently for Linux users.
The problem stems from CZipPackFile::GetFileInfo() (and CPackFile?) which is used when trying to open packed files.
Previously (at least in CS:S previous_build) it would do something like this:
CPackFileEntry entry;
entry.hash = HasStringCaselessConventional(filename);
int i = this->files.Find(entry);
if (i != -1)
{
// return file info here...
return 1;
}
return 0;Now it looks like it does something like this:
CPackFileEntry entry;
entry.hash = HasStringCaselessConventional(filename);
int i = this->files.Find(entry);
if (i != -1)
{
FileNameHandle_t f = this->filesystem_maybe->FindFileName_maybe(filename);
if (this->files[i].handle == f)
{
// return file info here...
return 1;
}
}
return 0;This is making its way to CUtilFilenameSymbolTable::FindFileName()
source-sdk-2013/src/tier1/utlsymbol.cpp
Lines 362 to 381 in aea94b3
| FileNameHandle_t CUtlFilenameSymbolTable::FindFileName( const char *pFileName ) | |
| { | |
| if ( !pFileName ) | |
| { | |
| return NULL; | |
| } | |
| // Fix slashes+dotslashes and make lower case first.. | |
| char fn[ MAX_PATH ]; | |
| Q_strncpy( fn, pFileName, sizeof( fn ) ); | |
| Q_RemoveDotSlashes( fn ); | |
| #ifdef _WIN32 | |
| Q_strlower( fn ); | |
| #endif | |
| // Split the filename into constituent parts | |
| char basepath[ MAX_PATH ]; | |
| Q_ExtractFilePath( fn, basepath, sizeof( basepath ) ); | |
| char filename[ MAX_PATH ]; | |
| Q_strncpy( filename, fn + Q_strlen( basepath ), sizeof( filename ) ); |
where it'll
Q_strlower(filename) only on Windows.
So even if the packed file did find a match case-insensitively, the FindFileName() causes it to fail.
(Same with CUtilFilenameSymbolTable::FindOrAddFileName())
source-sdk-2013/src/tier1/utlsymbol.cpp
Lines 312 to 332 in aea94b3
| FileNameHandle_t CUtlFilenameSymbolTable::FindOrAddFileName( const char *pFileName ) | |
| { | |
| if ( !pFileName ) | |
| { | |
| return NULL; | |
| } | |
| // find first | |
| FileNameHandle_t hFileName = FindFileName( pFileName ); | |
| if ( hFileName ) | |
| { | |
| return hFileName; | |
| } | |
| // Fix slashes+dotslashes and make lower case first.. | |
| char fn[ MAX_PATH ]; | |
| Q_strncpy( fn, pFileName, sizeof( fn ) ); | |
| Q_RemoveDotSlashes( fn ); | |
| #ifdef _WIN32 | |
| Q_strlower( fn ); | |
| #endif |
TL;DR: Remove the #ifdef _WIN32 wrapper around Q_strlower( fn ); in CUtlFilenameSymbolTable::FindFileName and CUtlFilenameSymbolTable::FindOrAddFileName.