engine: prevent extra malloc in exec by checking if cfg already contains newline at EOL and appending it to cbuf if required

This commit is contained in:
Alibek Omarov 2024-12-28 16:03:46 +03:00
parent 5d6cf48687
commit 14e79f04ac
3 changed files with 36 additions and 21 deletions

View file

@ -142,28 +142,33 @@ void Cbuf_AddFilteredText( const char *text )
Cbuf_InsertText Cbuf_InsertText
Adds command text immediately after the current command Adds command text immediately after the current command
Adds a \n to the text
============ ============
*/ */
static void Cbuf_InsertTextToBuffer( cmdbuf_t *buf, const char *text ) static void Cbuf_InsertTextToBuffer( cmdbuf_t *buf, const char *text, size_t len, size_t requested_len )
{ {
int l = Q_strlen( text ); if(( buf->cursize + requested_len ) >= buf->maxsize )
if(( buf->cursize + l ) >= buf->maxsize )
{ {
Con_Reportf( S_WARN "%s: overflow\n", __func__ ); Con_Reportf( S_WARN "%s: overflow\n", __func__ );
} }
else else
{ {
memmove( buf->data + l, buf->data, buf->cursize ); memmove( buf->data + len, buf->data, buf->cursize );
memcpy( buf->data, text, l ); memcpy( buf->data, text, len );
buf->cursize += l; buf->cursize += len;
} }
} }
void Cbuf_InsertTextLen( const char *text, size_t len, size_t requested_len )
{
// sometimes we need to insert more data than we have
// but also prevent overflow
Cbuf_InsertTextToBuffer( &cmd_text, text, len, requested_len );
}
void Cbuf_InsertText( const char *text ) void Cbuf_InsertText( const char *text )
{ {
Cbuf_InsertTextToBuffer( &cmd_text, text ); size_t l = Q_strlen( text );
Cbuf_InsertTextToBuffer( &cmd_text, text, l, l );
} }
/* /*
@ -1010,9 +1015,10 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
if( a ) if( a )
{ {
size_t len = Q_strlen( a->value );
Cbuf_InsertTextToBuffer( Cbuf_InsertTextToBuffer(
isPrivileged ? &cmd_text : &filteredcmd_text, isPrivileged ? &cmd_text : &filteredcmd_text,
a->value ); a->value, len, len );
return; return;
} }
} }

View file

@ -425,6 +425,7 @@ void Cbuf_AddText( const char *text );
void Cbuf_AddTextf( const char *text, ... ) FORMAT_CHECK( 1 ); void Cbuf_AddTextf( const char *text, ... ) FORMAT_CHECK( 1 );
void Cbuf_AddFilteredText( const char *text ); void Cbuf_AddFilteredText( const char *text );
void Cbuf_InsertText( const char *text ); void Cbuf_InsertText( const char *text );
void Cbuf_InsertTextLen( const char *text, size_t len, size_t requested_len );
void Cbuf_ExecStuffCmds( void ); void Cbuf_ExecStuffCmds( void );
void Cbuf_Execute (void); void Cbuf_Execute (void);
qboolean Cmd_CurrentCommandIsPrivileged( void ); qboolean Cmd_CurrentCommandIsPrivileged( void );

View file

@ -418,7 +418,6 @@ static void Host_Exec_f( void )
{ {
string cfgpath; string cfgpath;
byte *f; byte *f;
char *txt;
fs_offset_t len; fs_offset_t len;
if( Cmd_Argc() != 2 ) if( Cmd_Argc() != 2 )
@ -474,20 +473,29 @@ static void Host_Exec_f( void )
return; return;
} }
// len is fs_offset_t, which can be larger than size_t
if( len >= SIZE_MAX )
{
Con_Reportf( "%s: %s is too long\n", __func__, Cmd_Argv( 1 ));
return;
}
if( !Q_stricmp( "config.cfg", cfgpath )) if( !Q_stricmp( "config.cfg", cfgpath ))
host.config_executed = true; host.config_executed = true;
// adds \n\0 at end of the file
txt = Z_Calloc( len + 2 );
memcpy( txt, f, len );
txt[len] = '\n';
txt[len + 1] = '\0';
Mem_Free( f );
if( !host.apply_game_config ) if( !host.apply_game_config )
Con_Printf( "execing %s\n", Cmd_Argv( 1 )); Con_Printf( "execing %s\n", Cmd_Argv( 1 ));
Cbuf_InsertText( txt );
Mem_Free( txt ); // adds \n at end of the file
// FS_LoadFile always null terminates
if( f[len - 1] != '\n' )
{
Cbuf_InsertTextLen( f, len, len + 1 );
Cbuf_InsertTextLen( "\n", 1, 1 );
}
else Cbuf_InsertTextLen( f, len, len );
Mem_Free( f );
} }
/* /*