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
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 + l ) >= buf->maxsize )
if(( buf->cursize + requested_len ) >= buf->maxsize )
{
Con_Reportf( S_WARN "%s: overflow\n", __func__ );
}
else
{
memmove( buf->data + l, buf->data, buf->cursize );
memcpy( buf->data, text, l );
buf->cursize += l;
memmove( buf->data + len, buf->data, buf->cursize );
memcpy( buf->data, text, len );
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 )
{
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 )
{
size_t len = Q_strlen( a->value );
Cbuf_InsertTextToBuffer(
isPrivileged ? &cmd_text : &filteredcmd_text,
a->value );
a->value, len, len );
return;
}
}

View file

@ -425,6 +425,7 @@ void Cbuf_AddText( const char *text );
void Cbuf_AddTextf( const char *text, ... ) FORMAT_CHECK( 1 );
void Cbuf_AddFilteredText( 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_Execute (void);
qboolean Cmd_CurrentCommandIsPrivileged( void );

View file

@ -418,8 +418,7 @@ static void Host_Exec_f( void )
{
string cfgpath;
byte *f;
char *txt;
fs_offset_t len;
fs_offset_t len;
if( Cmd_Argc() != 2 )
{
@ -474,20 +473,29 @@ static void Host_Exec_f( void )
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 ))
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 )
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 );
}
/*