mirror of
https://github.com/UberGames/lilium-voyager.git
synced 2024-12-13 05:31:29 +00:00
- Fix potential out-of-bounds read in files.c, fix by using new FS_IsExt
- Add capability to load demos with com_protocol suffix, partially applied patches from Simon McVittie - Fix demo loading if protocol number has more digits than 2 - Minor refactoring, replace all occurances of suffix "dm_" with global macro DEMOEXT
This commit is contained in:
parent
fef4d12d68
commit
c0cca7a0a8
6 changed files with 125 additions and 48 deletions
|
@ -627,14 +627,14 @@ void CL_Record_f( void ) {
|
||||||
if ( Cmd_Argc() == 2 ) {
|
if ( Cmd_Argc() == 2 ) {
|
||||||
s = Cmd_Argv(1);
|
s = Cmd_Argv(1);
|
||||||
Q_strncpyz( demoName, s, sizeof( demoName ) );
|
Q_strncpyz( demoName, s, sizeof( demoName ) );
|
||||||
Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, PROTOCOL_VERSION );
|
Com_sprintf (name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer );
|
||||||
} else {
|
} else {
|
||||||
int number;
|
int number;
|
||||||
|
|
||||||
// scan for a free demo name
|
// scan for a free demo name
|
||||||
for ( number = 0 ; number <= 9999 ; number++ ) {
|
for ( number = 0 ; number <= 9999 ; number++ ) {
|
||||||
CL_DemoFilename( number, demoName );
|
CL_DemoFilename( number, demoName );
|
||||||
Com_sprintf (name, sizeof(name), "demos/%s.dm_%d", demoName, PROTOCOL_VERSION );
|
Com_sprintf (name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_protocol->integer );
|
||||||
|
|
||||||
if (!FS_FileExists(name))
|
if (!FS_FileExists(name))
|
||||||
break; // file doesn't exist
|
break; // file doesn't exist
|
||||||
|
@ -884,9 +884,22 @@ static void CL_WalkDemoExt(char *arg, char *name, int *demofile)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
*demofile = 0;
|
*demofile = 0;
|
||||||
|
|
||||||
|
Com_sprintf (name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, com_protocol->integer);
|
||||||
|
|
||||||
|
FS_FOpenFileRead( name, demofile, qtrue );
|
||||||
|
|
||||||
|
if (*demofile)
|
||||||
|
{
|
||||||
|
Com_Printf("Demo file: %s\n", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Com_Printf("Not found: %s\n", name);
|
||||||
|
|
||||||
while(demo_protocols[i])
|
while(demo_protocols[i])
|
||||||
{
|
{
|
||||||
Com_sprintf (name, MAX_OSPATH, "demos/%s.dm_%d", arg, demo_protocols[i]);
|
Com_sprintf (name, MAX_OSPATH, "demos/%s.%s%d", arg, DEMOEXT, demo_protocols[i]);
|
||||||
FS_FOpenFileRead( name, demofile, qtrue );
|
FS_FOpenFileRead( name, demofile, qtrue );
|
||||||
if (*demofile)
|
if (*demofile)
|
||||||
{
|
{
|
||||||
|
@ -910,7 +923,7 @@ static void CL_CompleteDemoName( char *args, int argNum )
|
||||||
{
|
{
|
||||||
char demoExt[ 16 ];
|
char demoExt[ 16 ];
|
||||||
|
|
||||||
Com_sprintf( demoExt, sizeof( demoExt ), ".dm_%d", PROTOCOL_VERSION );
|
Com_sprintf(demoExt, sizeof(demoExt), ".%s%d", DEMOEXT, com_protocol->integer);
|
||||||
Field_CompleteFilename( "demos", demoExt, qtrue, qtrue );
|
Field_CompleteFilename( "demos", demoExt, qtrue, qtrue );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -943,34 +956,41 @@ void CL_PlayDemo_f( void ) {
|
||||||
|
|
||||||
CL_Disconnect( qtrue );
|
CL_Disconnect( qtrue );
|
||||||
|
|
||||||
// check for an extension .dm_?? (?? is protocol)
|
// check for an extension .DEMOEXT_?? (?? is protocol)
|
||||||
ext_test = arg + strlen(arg) - 6;
|
ext_test = Q_strrchr(arg, '.');
|
||||||
if ((strlen(arg) > 6) && (ext_test[0] == '.') &&
|
|
||||||
((ext_test[1] == 'd') || (ext_test[1] == 'D')) &&
|
if(ext_test && !Q_stricmpn(ext_test + 1, DEMOEXT, ARRAY_LEN(DEMOEXT) - 1))
|
||||||
((ext_test[2] == 'm') || (ext_test[2] == 'M')) &&
|
|
||||||
(ext_test[3] == '_'))
|
|
||||||
{
|
{
|
||||||
protocol = atoi(ext_test+4);
|
protocol = atoi(ext_test + ARRAY_LEN(DEMOEXT));
|
||||||
i=0;
|
|
||||||
while(demo_protocols[i])
|
for(i = 0; demo_protocols[i]; i++)
|
||||||
{
|
{
|
||||||
if (demo_protocols[i] == protocol)
|
if(demo_protocols[i] == protocol)
|
||||||
break;
|
break;
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
if (demo_protocols[i])
|
|
||||||
|
if(demo_protocols[i] || protocol == com_protocol->integer)
|
||||||
{
|
{
|
||||||
Com_sprintf (name, sizeof(name), "demos/%s", arg);
|
Com_sprintf(name, sizeof(name), "demos/%s", arg);
|
||||||
FS_FOpenFileRead( name, &clc.demofile, qtrue );
|
FS_FOpenFileRead(name, &clc.demofile, qtrue);
|
||||||
} else {
|
}
|
||||||
Com_Printf("Protocol %d not supported for demos\n", protocol);
|
else
|
||||||
Q_strncpyz(retry, arg, sizeof(retry));
|
{
|
||||||
retry[strlen(retry)-6] = 0;
|
int len;
|
||||||
CL_WalkDemoExt( retry, name, &clc.demofile );
|
|
||||||
|
Com_Printf("Protocol %d not supported for demos\n", protocol);
|
||||||
|
len = ext_test - arg;
|
||||||
|
|
||||||
|
if(len >= ARRAY_LEN(retry))
|
||||||
|
len = ARRAY_LEN(retry) - 1;
|
||||||
|
|
||||||
|
Q_strncpyz(retry, arg, len + 1);
|
||||||
|
retry[len] = '\0';
|
||||||
|
CL_WalkDemoExt(retry, name, &clc.demofile);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
CL_WalkDemoExt( arg, name, &clc.demofile );
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
CL_WalkDemoExt(arg, name, &clc.demofile);
|
||||||
|
|
||||||
if (!clc.demofile) {
|
if (!clc.demofile) {
|
||||||
Com_Error( ERR_DROP, "couldn't open %s", name);
|
Com_Error( ERR_DROP, "couldn't open %s", name);
|
||||||
|
|
|
@ -223,7 +223,7 @@ static void Demos_MenuInit( void ) {
|
||||||
s_demos.list.generic.y = 130;
|
s_demos.list.generic.y = 130;
|
||||||
s_demos.list.width = 16;
|
s_demos.list.width = 16;
|
||||||
s_demos.list.height = 14;
|
s_demos.list.height = 14;
|
||||||
Com_sprintf(extension, sizeof(extension), "dm_%d", (int)trap_Cvar_VariableValue( "protocol" ) );
|
Com_sprintf(extension, sizeof(extension), ".%s%d", DEMOEXT, (int) trap_Cvar_VariableValue("protocol"));
|
||||||
s_demos.list.numitems = trap_FS_GetFileList( "demos", extension, s_demos.names, NAMEBUFSIZE );
|
s_demos.list.numitems = trap_FS_GetFileList( "demos", extension, s_demos.names, NAMEBUFSIZE );
|
||||||
s_demos.list.itemnames = (const char **)s_demos.demolist;
|
s_demos.list.itemnames = (const char **)s_demos.demolist;
|
||||||
s_demos.list.columns = 3;
|
s_demos.list.columns = 3;
|
||||||
|
|
|
@ -941,6 +941,59 @@ qboolean FS_FilenameCompare( const char *s1, const char *s2 ) {
|
||||||
return qfalse; // strings are equal
|
return qfalse; // strings are equal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========
|
||||||
|
FS_IsExt
|
||||||
|
|
||||||
|
Return qtrue if ext matches file extension filename
|
||||||
|
===========
|
||||||
|
*/
|
||||||
|
|
||||||
|
qboolean FS_IsExt(const char *filename, const char *ext, int namelen)
|
||||||
|
{
|
||||||
|
int extlen;
|
||||||
|
|
||||||
|
extlen = strlen(ext);
|
||||||
|
|
||||||
|
if(extlen > namelen)
|
||||||
|
return qfalse;
|
||||||
|
|
||||||
|
filename += namelen - extlen;
|
||||||
|
|
||||||
|
return !Q_stricmp(filename, ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
===========
|
||||||
|
FS_IsDemoExt
|
||||||
|
|
||||||
|
Return qtrue if filename has a demo extension
|
||||||
|
===========
|
||||||
|
*/
|
||||||
|
|
||||||
|
qboolean FS_IsDemoExt(const char *filename, int namelen)
|
||||||
|
{
|
||||||
|
char *ext_test;
|
||||||
|
int index, protocol;
|
||||||
|
|
||||||
|
ext_test = Q_strrchr(filename, '.');
|
||||||
|
if(ext_test && !Q_stricmpn(ext_test + 1, DEMOEXT, ARRAY_LEN(DEMOEXT) - 1))
|
||||||
|
{
|
||||||
|
protocol = atoi(ext_test + ARRAY_LEN(DEMOEXT));
|
||||||
|
|
||||||
|
if(protocol == com_protocol->integer)
|
||||||
|
return qtrue;
|
||||||
|
|
||||||
|
for(index = 0; demo_protocols[index]; index++)
|
||||||
|
{
|
||||||
|
if(demo_protocols[index] == protocol)
|
||||||
|
return qtrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========
|
===========
|
||||||
FS_FOpenFileRead
|
FS_FOpenFileRead
|
||||||
|
@ -962,7 +1015,6 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
|
||||||
long hash;
|
long hash;
|
||||||
FILE *temp;
|
FILE *temp;
|
||||||
int l;
|
int l;
|
||||||
char demoExt[16];
|
|
||||||
|
|
||||||
hash = 0;
|
hash = 0;
|
||||||
|
|
||||||
|
@ -1009,7 +1061,6 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
|
||||||
Com_Error( ERR_FATAL, "FS_FOpenFileRead: NULL 'filename' parameter passed\n" );
|
Com_Error( ERR_FATAL, "FS_FOpenFileRead: NULL 'filename' parameter passed\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
Com_sprintf (demoExt, sizeof(demoExt), ".dm_%d",PROTOCOL_VERSION );
|
|
||||||
// qpaths are not supposed to have a leading slash
|
// qpaths are not supposed to have a leading slash
|
||||||
if ( filename[0] == '/' || filename[0] == '\\' ) {
|
if ( filename[0] == '/' || filename[0] == '\\' ) {
|
||||||
filename++;
|
filename++;
|
||||||
|
@ -1061,16 +1112,19 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
|
||||||
// shaders, txt, arena files by themselves do not count as a reference as
|
// shaders, txt, arena files by themselves do not count as a reference as
|
||||||
// these are loaded from all pk3s
|
// these are loaded from all pk3s
|
||||||
// from every pk3 file..
|
// from every pk3 file..
|
||||||
l = strlen( filename );
|
l = strlen(filename);
|
||||||
if ( !(pak->referenced & FS_GENERAL_REF)) {
|
|
||||||
if ( Q_stricmp(filename + l - 7, ".shader") != 0 &&
|
if (!(pak->referenced & FS_GENERAL_REF))
|
||||||
Q_stricmp(filename + l - 4, ".txt") != 0 &&
|
{
|
||||||
Q_stricmp(filename + l - 4, ".cfg") != 0 &&
|
if(!FS_IsExt(filename, ".shader", l) &&
|
||||||
Q_stricmp(filename + l - 7, ".config") != 0 &&
|
!FS_IsExt(filename, ".txt", l) &&
|
||||||
strstr(filename, "levelshots") == NULL &&
|
!FS_IsExt(filename, ".cfg", l) &&
|
||||||
Q_stricmp(filename + l - 4, ".bot") != 0 &&
|
!FS_IsExt(filename, ".config", l) &&
|
||||||
Q_stricmp(filename + l - 6, ".arena") != 0 &&
|
!FS_IsExt(filename, ".bot", l) &&
|
||||||
Q_stricmp(filename + l - 5, ".menu") != 0) {
|
!FS_IsExt(filename, ".arena", l) &&
|
||||||
|
!FS_IsExt(filename, ".menu", l) &&
|
||||||
|
!strstr(filename, "levelshots"))
|
||||||
|
{
|
||||||
pak->referenced |= FS_GENERAL_REF;
|
pak->referenced |= FS_GENERAL_REF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1121,13 +1175,14 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
|
||||||
// this test can make the search fail although the file is in the directory
|
// this test can make the search fail although the file is in the directory
|
||||||
// I had the problem on https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=8
|
// I had the problem on https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=8
|
||||||
// turned out I used FS_FileExists instead
|
// turned out I used FS_FileExists instead
|
||||||
if ( fs_numServerPaks ) {
|
if(fs_numServerPaks)
|
||||||
|
{
|
||||||
if ( Q_stricmp( filename + l - 4, ".cfg" ) // for config files
|
if(!FS_IsExt(filename, ".cfg", l) && // for config files
|
||||||
&& Q_stricmp( filename + l - 5, ".menu" ) // menu files
|
!FS_IsExt(filename, ".menu", l) && // menu files
|
||||||
&& Q_stricmp( filename + l - 5, ".game" ) // menu files
|
!FS_IsExt(filename, ".game", l) && // menu files
|
||||||
&& Q_stricmp( filename + l - strlen(demoExt), demoExt ) // menu files
|
!FS_IsExt(filename, ".cfg", l) && // for journal files
|
||||||
&& Q_stricmp( filename + l - 4, ".dat" ) ) { // for journal files
|
!FS_IsDemoExt(filename, l)) // demos
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#define MAX_TEAMNAME 32
|
#define MAX_TEAMNAME 32
|
||||||
#define MAX_MASTER_SERVERS 5 // number of supported master servers
|
#define MAX_MASTER_SERVERS 5 // number of supported master servers
|
||||||
|
|
||||||
|
#define DEMOEXT "dm_" // standard demo extension
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||||
|
|
|
@ -162,7 +162,7 @@ void UI_LoadBestScores(const char *map, int game) {
|
||||||
}
|
}
|
||||||
UI_SetBestScores(&newInfo, qfalse);
|
UI_SetBestScores(&newInfo, qfalse);
|
||||||
|
|
||||||
Com_sprintf(fileName, MAX_QPATH, "demos/%s_%d.dm_%d", map, game, (int)trap_Cvar_VariableValue("protocol"));
|
Com_sprintf(fileName, MAX_QPATH, "demos/%s_%d.%s%d", map, game, DEMOEXT, (int)trap_Cvar_VariableValue("protocol"));
|
||||||
uiInfo.demoAvailable = qfalse;
|
uiInfo.demoAvailable = qfalse;
|
||||||
if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
|
if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
|
||||||
uiInfo.demoAvailable = qtrue;
|
uiInfo.demoAvailable = qtrue;
|
||||||
|
|
|
@ -2877,11 +2877,11 @@ static void UI_LoadDemos( void ) {
|
||||||
char *demoname;
|
char *demoname;
|
||||||
int i, len;
|
int i, len;
|
||||||
|
|
||||||
Com_sprintf(demoExt, sizeof(demoExt), "dm_%d", (int)trap_Cvar_VariableValue("protocol"));
|
Com_sprintf(demoExt, sizeof(demoExt), "%s%d", DEMOEXT, (int)trap_Cvar_VariableValue("protocol"));
|
||||||
|
|
||||||
uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, 4096 );
|
uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, 4096 );
|
||||||
|
|
||||||
Com_sprintf(demoExt, sizeof(demoExt), ".dm_%d", (int)trap_Cvar_VariableValue("protocol"));
|
Com_sprintf(demoExt, sizeof(demoExt), ".%s%d", DEMOEXT, (int)trap_Cvar_VariableValue("protocol"));
|
||||||
|
|
||||||
if (uiInfo.demoCount) {
|
if (uiInfo.demoCount) {
|
||||||
if (uiInfo.demoCount > MAX_DEMOS) {
|
if (uiInfo.demoCount > MAX_DEMOS) {
|
||||||
|
|
Loading…
Reference in a new issue