Skip to content

Commit

Permalink
engine: prevent extra malloc in exec by checking if cfg already conta…
Browse files Browse the repository at this point in the history
…ins newline at EOL and appending it to cbuf if required
  • Loading branch information
a1batross committed Dec 28, 2024
1 parent 5d6cf48 commit 14e79f0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 21 deletions.
26 changes: 16 additions & 10 deletions engine/common/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}

/*
Expand Down Expand Up @@ -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;
}
}
Expand Down
1 change: 1 addition & 0 deletions engine/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down
30 changes: 19 additions & 11 deletions engine/common/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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 );
}

/*
Expand Down

0 comments on commit 14e79f0

Please sign in to comment.