Skip to content

[Bug] Linux CUtilFilenameSymbolTable conflicts with packed-file casing #865

@rtldg

Description

@rtldg

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()

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())

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions