engine: introduce COM_ParseFileSafe, add tests

This commit is contained in:
Alibek Omarov 2021-09-30 16:07:24 +03:00 committed by a1batross
parent a3a8acfe6c
commit a235bec5f1
3 changed files with 81 additions and 27 deletions

View File

@ -476,11 +476,11 @@ COM_ParseFile
text parser
==============
*/
char *COM_ParseFile( char *data, char *token )
char *COM_ParseFileSafe( char *data, char *token, const size_t size )
{
int c, len;
if( !token )
if( !token || !size )
return NULL;
len = 0;
@ -498,7 +498,7 @@ skipwhite:
}
// skip // comments
if( c=='/' && data[1] == '/' )
if( c == '/' && data[1] == '/' )
{
while( *data && *data != '\n' )
data++;
@ -523,7 +523,13 @@ skipwhite:
if( c == '\\' && *data == '"' )
{
token[len++] = (byte)*data++;
if( len + 1 < size )
{
token[len] = (byte)*data;
len++;
}
data++;
continue;
}
@ -532,26 +538,43 @@ skipwhite:
token[len] = 0;
return data;
}
token[len] = c;
len++;
if( len + 1 < size )
{
token[len] = c;
len++;
}
}
}
// parse single characters
if( COM_IsSingleChar( c ))
{
token[len] = c;
len++;
token[len] = 0;
return data + 1;
if( size >= 2 ) // char and \0
{
token[len] = c;
len++;
token[len] = 0;
return data + 1;
}
else
{
// couldn't pass anything
token[0] = 0;
return data;
}
}
// parse a regular word
do
{
token[len] = c;
if( len + 1 < size )
{
token[len] = c;
len++;
}
data++;
len++;
c = ((byte)*data);
if( COM_IsSingleChar( c ))
@ -563,6 +586,19 @@ skipwhite:
return data;
}
/*
================
COM_ParseFile
old unsafe version of ParseFile, deprecated
only for API compatibility
================
*/
char *COM_ParseFile( char *data, char *token )
{
return COM_ParseFileSafe( data, token, -1 );
}
/*
================
COM_ParseVector
@ -613,21 +649,6 @@ qboolean COM_ParseVector( char **pfile, float *v, size_t size )
return false;
}
/*
=============
COM_CheckString
=============
*/
#if 0
int COM_CheckString( const char *string )
{
if( !string || !*string )
return 0;
return 1;
}
#endif
/*
=============
COM_FileSize
@ -1296,3 +1317,34 @@ only exists in PlayStation version
void GAME_EXPORT pfnResetTutorMessageDecayData( void )
{
}
#if XASH_ENGINE_TESTS
#include "tests.h"
void Test_RunCommon( void )
{
char *file = (char*)"q asdf \"qwerty\" \"f \\\"f\" meowmeow\n// comment \"stuff ignored\"\nbark";
char buf[5];
Msg( "Checking COM_ParseFile...\n" );
file = COM_ParseFileSafe( file, buf, sizeof( buf ));
TASSERT( !Q_strcmp( buf, "q" ));
file = COM_ParseFileSafe( file, buf, sizeof( buf ));
TASSERT( !Q_strcmp( buf, "asdf" ));
file = COM_ParseFileSafe( file, buf, sizeof( buf ));
TASSERT( !Q_strcmp( buf, "qwer" ));
file = COM_ParseFileSafe( file, buf, sizeof( buf ));
TASSERT( !Q_strcmp( buf, "f \"f" ));
file = COM_ParseFileSafe( file, buf, sizeof( buf ));
TASSERT( !Q_strcmp( buf, "meow" ));
file = COM_ParseFileSafe( file, buf, sizeof( buf ));
TASSERT( !Q_strcmp( buf, "bark" ));
}
#endif

View File

@ -855,6 +855,7 @@ void CL_CharEvent( int key );
qboolean CL_DisableVisibility( void );
int CL_PointContents( const vec3_t point );
char *COM_ParseFile( char *data, char *token );
char *COM_ParseFileSafe( char *data, char *token, const size_t size );
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength );
int CL_GetDemoComment( const char *demoname, char *comment );
void COM_AddAppDirectoryToSearchPath( const char *pszBaseDir, const char *appName );

View File

@ -783,6 +783,7 @@ static void Host_RunTests( int stage )
case 0: // early engine load
memset( &tests_stats, 0, sizeof( tests_stats ));
Test_RunLibCommon();
Test_RunCommon();
break;
case 1: // after FS load
Test_RunImagelib();