From 52dd6193bfe2f7f42dc5eb986f2cc075fadc6030 Mon Sep 17 00:00:00 2001 From: Stephen Saunders Date: Tue, 20 Jun 2023 12:24:24 -0400 Subject: [PATCH] Replace sprintf() / vsprintf() with idStr::snPrintf() / idStr::vsnPrintf() for buffer security --- doomclassic/doom/am_map.cpp | 4 +-- doomclassic/doom/d_main.cpp | 16 +++++----- doomclassic/doom/doominterface.cpp | 2 +- doomclassic/doom/f_finale.cpp | 2 +- doomclassic/doom/g_game.cpp | 10 +++--- doomclassic/doom/hu_stuff.cpp | 2 +- doomclassic/doom/i_sound_openal.cpp | 4 +-- doomclassic/doom/i_system.cpp | 4 +-- doomclassic/doom/m_menu.cpp | 10 +++--- doomclassic/doom/p_setup.cpp | 4 +-- doomclassic/doom/st_stuff.cpp | 22 ++++++------- doomclassic/doom/wi_stuff.cpp | 8 ++--- neo/cm/CollisionModel_debug.cpp | 8 ++--- neo/d3xp/MultiplayerGame.cpp | 2 +- neo/d3xp/Weapon.cpp | 2 +- neo/d3xp/gamesys/Event.cpp | 10 +++--- neo/d3xp/gamesys/SaveGame.cpp | 2 +- neo/d3xp/gamesys/SysCmds.cpp | 2 +- neo/d3xp/gamesys/SysCvar.cpp | 2 +- neo/d3xp/script/Script_Compiler.cpp | 4 +-- neo/d3xp/script/Script_Interpreter.cpp | 4 +-- neo/d3xp/script/Script_Interpreter.h | 4 +-- neo/d3xp/script/Script_Thread.cpp | 4 +-- neo/framework/Common.cpp | 2 +- neo/framework/Common_printf.cpp | 4 +-- neo/framework/Console.cpp | 4 +++ neo/framework/DeclAF.cpp | 2 +- neo/framework/DeclManager.cpp | 2 +- neo/framework/File.cpp | 42 +++++++++++++------------ neo/framework/TokenParser.cpp | 4 +-- neo/idlib/Lexer.cpp | 4 +-- neo/idlib/Parser.cpp | 14 ++++----- neo/idlib/Str.cpp | 43 ++++++++++++++------------ neo/idlib/Str.h | 16 +++++----- neo/renderer/ImageManager.cpp | 4 +-- neo/renderer/Image_files.cpp | 4 +-- neo/renderer/ModelManager.cpp | 2 +- neo/sys/sdl/sdl_cpu.cpp | 20 ++++++------ neo/sys/sys_local.cpp | 6 ++-- neo/sys/sys_session_local.cpp | 2 +- neo/tools/compilers/aas/Brush.cpp | 2 +- neo/ui/DeviceContext.cpp | 5 +-- neo/ui/UserInterface.cpp | 2 +- neo/ui/Window.cpp | 10 +++--- 44 files changed, 170 insertions(+), 156 deletions(-) diff --git a/doomclassic/doom/am_map.cpp b/doomclassic/doom/am_map.cpp index 88be2dc9..3bc0e596 100644 --- a/doomclassic/doom/am_map.cpp +++ b/doomclassic/doom/am_map.cpp @@ -429,7 +429,7 @@ void AM_loadPics( void ) for( i = 0; i < 10; i++ ) { - sprintf( namebuf, "AMMNUM%d", i ); + idStr::snPrintf( namebuf, sizeof( namebuf ), "AMMNUM%d", i ); ::g->marknums[i] = ( patch_t* )W_CacheLumpName( namebuf, PU_STATIC_SHARED ); } @@ -635,7 +635,7 @@ AM_Responder ::g->amap_plr->message = ::g->grid ? AMSTR_GRIDON : AMSTR_GRIDOFF; break; case AM_MARKKEY: - sprintf( ::g->buffer, "%s %d", AMSTR_MARKEDSPOT, ::g->markpointnum ); + idStr::snPrintf( ::g->buffer, sizeof( ::g->buffer ), "%s %d", AMSTR_MARKEDSPOT, ::g->markpointnum ); ::g->amap_plr->message = ::g->buffer; AM_addMark(); break; diff --git a/doomclassic/doom/d_main.cpp b/doomclassic/doom/d_main.cpp index 03001949..b7432f3b 100644 --- a/doomclassic/doom/d_main.cpp +++ b/doomclassic/doom/d_main.cpp @@ -612,35 +612,35 @@ void D_DoomMain( void ) switch( ::g->gamemode ) { case retail: - sprintf( ::g->title, + idStr::snPrintf( ::g->title, sizeof( ::g->title ), " " "The Ultimate DOOM Startup v%i.%i" " ", VERSION / 100, VERSION % 100 ); break; case shareware: - sprintf( ::g->title, + idStr::snPrintf( ::g->title, sizeof( ::g->title ), " " "DOOM Shareware Startup v%i.%i" " ", VERSION / 100, VERSION % 100 ); break; case registered: - sprintf( ::g->title, + idStr::snPrintf( ::g->title, sizeof( ::g->title ), " " "DOOM Registered Startup v%i.%i" " ", VERSION / 100, VERSION % 100 ); break; case commercial: - sprintf( ::g->title, + idStr::snPrintf( ::g->title, sizeof( ::g->title ), " " "DOOM 2: Hell on Earth v%i.%i" " ", VERSION / 100, VERSION % 100 ); break; default: - sprintf( ::g->title, + idStr::snPrintf( ::g->title, sizeof( ::g->title ), " " "Public DOOM - v%i.%i" " ", @@ -686,7 +686,7 @@ void D_DoomMain( void ) if( p && p < ::g->myargc - 1 ) { - sprintf( file, "d:\\%s.lmp", ::g->myargv[p + 1] ); + idStr::snPrintf( file, sizeof( file ), "d:\\%s.lmp", ::g->myargv[p + 1] ); D_AddFile( file ); I_Printf( "Playing demo %s.lmp.\n", ::g->myargv[p + 1] ); } @@ -918,11 +918,11 @@ bool D_DoomMainPoll( void ) { if( M_CheckParm( "-cdrom" ) ) { - sprintf( file, "c:\\doomdata\\" SAVEGAMENAME "%c.dsg", ::g->myargv[p + 1][0] ); + idStr::snPrintf( file, sizeof( file ), "c:\\doomdata\\" SAVEGAMENAME "%c.dsg", ::g->myargv[p + 1][0] ); } else { - sprintf( file, SAVEGAMENAME "%c.dsg", ::g->myargv[p + 1][0] ); + idStr::snPrintf( file, sizeof( file ), SAVEGAMENAME "%c.dsg", ::g->myargv[p + 1][0] ); } G_LoadGame( file ); } diff --git a/doomclassic/doom/doominterface.cpp b/doomclassic/doom/doominterface.cpp index 30b64632..47943f52 100644 --- a/doomclassic/doom/doominterface.cpp +++ b/doomclassic/doom/doominterface.cpp @@ -327,7 +327,7 @@ void DoomInterface::SetMultiplayerPlayers( int localPlayerIndex, int playerCount strcpy( mpArgV[localPlayerIndex][2], "1" ); strcpy( mpArgV[localPlayerIndex][3], "-net" ); - sprintf( mpArgV[localPlayerIndex][4], "%d", localPlayer ); + idStr::snPrintf( mpArgV[localPlayerIndex][4], sizeof( mpArgV[localPlayerIndex][4] ), "%d", localPlayer ); strcpy( mpArgV[localPlayerIndex][5], playerAddresses[localPlayer].c_str() ); int currentArg = 6; diff --git a/doomclassic/doom/f_finale.cpp b/doomclassic/doom/f_finale.cpp index 73aa46a8..3eac719a 100755 --- a/doomclassic/doom/f_finale.cpp +++ b/doomclassic/doom/f_finale.cpp @@ -884,7 +884,7 @@ void F_BunnyScroll( void ) ::g->laststage = stage; } - snprintf( name, name_len, "END%i", stage ); + idStr::snPrintf( name, name_len, "END%i", stage ); V_DrawPatch( ( ORIGINAL_WIDTH - 13 * 8 ) / 2, ( ORIGINAL_HEIGHT - 8 * 8 ) / 2, 0, ( patch_t* )W_CacheLumpName( name, PU_CACHE_SHARED ) ); } diff --git a/doomclassic/doom/g_game.cpp b/doomclassic/doom/g_game.cpp index 1ba13ca8..93f65808 100644 --- a/doomclassic/doom/g_game.cpp +++ b/doomclassic/doom/g_game.cpp @@ -1587,7 +1587,7 @@ qboolean G_DoLoadGame() // skip the description field memset( vcheck, 0, sizeof( vcheck ) ); - sprintf( vcheck, "version %i", VERSION ); + idStr::snPrintf( vcheck, sizeof( vcheck ), "version %i", VERSION ); if( strcmp( ( char* )::g->save_p, vcheck ) ) { loadingGame = false; @@ -1679,17 +1679,17 @@ qboolean G_DoSaveGame( void ) if( common->GetCurrentGame() == DOOM_CLASSIC ) { - sprintf( name, "DOOM\\%s%d.dsg", SAVEGAMENAME, ::g->savegameslot ); + idStr::snPrintf( name, sizeof( name ), "DOOM\\%s%d.dsg", SAVEGAMENAME, ::g->savegameslot ); } else { if( DoomLib::expansionSelected == doom2 ) { - sprintf( name, "DOOM2\\%s%d.dsg", SAVEGAMENAME, ::g->savegameslot ); + idStr::snPrintf( name, sizeof( name ), "DOOM2\\%s%d.dsg", SAVEGAMENAME, ::g->savegameslot ); } else { - sprintf( name, "DOOM2_NRFTL\\%s%d.dsg", SAVEGAMENAME, ::g->savegameslot ); + idStr::snPrintf( name, sizeof( name ), "DOOM2_NRFTL\\%s%d.dsg", SAVEGAMENAME, ::g->savegameslot ); } } @@ -1700,7 +1700,7 @@ qboolean G_DoSaveGame( void ) ::g->save_p += SAVESTRINGSIZE; memset( name2, 0, sizeof( name2 ) ); - sprintf( name2, "version %i", VERSION ); + idStr::snPrintf( name2, sizeof( name2 ), "version %i", VERSION ); memcpy( ::g->save_p, name2, VERSIONSIZE ); ::g->save_p += VERSIONSIZE; diff --git a/doomclassic/doom/hu_stuff.cpp b/doomclassic/doom/hu_stuff.cpp index d5995c83..8347d7df 100755 --- a/doomclassic/doom/hu_stuff.cpp +++ b/doomclassic/doom/hu_stuff.cpp @@ -328,7 +328,7 @@ void HU_Init( void ) j = HU_FONTSTART; for( i = 0; i < HU_FONTSIZE; i++ ) { - snprintf( buffer, buffer_len, "STCFN%03d", j++ ); + idStr::snPrintf( buffer, buffer_len, "STCFN%03d", j++ ); ::g->hu_font[i] = ( patch_t* ) W_CacheLumpName( buffer, PU_STATIC_SHARED ); } diff --git a/doomclassic/doom/i_sound_openal.cpp b/doomclassic/doom/i_sound_openal.cpp index 7c794cf0..91b87dc9 100644 --- a/doomclassic/doom/i_sound_openal.cpp +++ b/doomclassic/doom/i_sound_openal.cpp @@ -163,7 +163,7 @@ void* getsfx( const char* sfxname, int* len ) //float scale = 1.0f; // Get the sound data from the WAD - sprintf( name, "ds%s", sfxname ); + idStr::snPrintf( name, sizeof( name ), "ds%s", sfxname ); // Scale down the plasma gun, it clips //if ( strcmp( sfxname, "plasma" ) == 0 ) { @@ -243,7 +243,7 @@ I_GetSfxLumpNum int I_GetSfxLumpNum( sfxinfo_t* sfx ) { char namebuf[9]; - sprintf( namebuf, "ds%s", sfx->name ); + idStr::snPrintf( namebuf, sizeof( namebuf ), "ds%s", sfx->name ); return W_GetNumForName( namebuf ); } diff --git a/doomclassic/doom/i_system.cpp b/doomclassic/doom/i_system.cpp index 791389bc..85a182c3 100644 --- a/doomclassic/doom/i_system.cpp +++ b/doomclassic/doom/i_system.cpp @@ -135,7 +135,7 @@ void I_Printf( const char* msg, ... ) if( debugOutput ) { va_start( argptr, msg ); - vsprintf( pmsg, msg, argptr ); + idStr::vsnPrintf( pmsg, sizeof( pmsg ), msg, argptr ); safeOutputDebug( pmsg ); @@ -153,7 +153,7 @@ void I_PrintfE( const char* msg, ... ) if( debugOutput ) { va_start( argptr, msg ); - vsprintf( pmsg, msg, argptr ); + idStr::vsnPrintf( pmsg, sizeof( pmsg ), msg, argptr ); safeOutputDebug( "ERROR: " ); safeOutputDebug( pmsg ); diff --git a/doomclassic/doom/m_menu.cpp b/doomclassic/doom/m_menu.cpp index 45a4f9b8..f2d411fd 100644 --- a/doomclassic/doom/m_menu.cpp +++ b/doomclassic/doom/m_menu.cpp @@ -261,17 +261,17 @@ void M_ReadSaveStrings( void ) { if( common->GetCurrentGame() == DOOM_CLASSIC ) { - sprintf( name, "DOOM\\%s%d.dsg", SAVEGAMENAME, i ); + idStr::snPrintf( name, sizeof( name ), "DOOM\\%s%d.dsg", SAVEGAMENAME, i ); } else { if( DoomLib::idealExpansion == doom2 ) { - sprintf( name, "DOOM2\\%s%d.dsg", SAVEGAMENAME, i ); + idStr::snPrintf( name, sizeof( name ), "DOOM2\\%s%d.dsg", SAVEGAMENAME, i ); } else { - sprintf( name, "DOOM2_NRFTL\\%s%d.dsg", SAVEGAMENAME, i ); + idStr::snPrintf( name, sizeof( name ), "DOOM2_NRFTL\\%s%d.dsg", SAVEGAMENAME, i ); } } @@ -520,7 +520,7 @@ void M_QuickSave( void ) ::g->quickSaveSlot = -2; // means to pick a slot now return; } - sprintf( ::g->tempstring, QSPROMPT, ::g->savegamestrings[::g->quickSaveSlot] ); + idStr::snPrintf( ::g->tempstring, sizeof( ::g->tempstring ), QSPROMPT, ::g->savegamestrings[::g->quickSaveSlot] ); M_StartMessage( ::g->tempstring, M_QuickSaveResponse, true ); } @@ -552,7 +552,7 @@ void M_QuickLoad( void ) M_StartMessage( QSAVESPOT, NULL, false ); return; } - sprintf( ::g->tempstring, QLPROMPT, ::g->savegamestrings[::g->quickSaveSlot] ); + idStr::snPrintf( ::g->tempstring, sizeof( ::g->tempstring ), QLPROMPT, ::g->savegamestrings[::g->quickSaveSlot] ); M_StartMessage( ::g->tempstring, M_QuickLoadResponse, true ); } diff --git a/doomclassic/doom/p_setup.cpp b/doomclassic/doom/p_setup.cpp index ed5f4f0e..15a114f7 100644 --- a/doomclassic/doom/p_setup.cpp +++ b/doomclassic/doom/p_setup.cpp @@ -687,11 +687,11 @@ P_SetupLevel { if( map < 10 ) { - sprintf( lumpname, "map0%i", map % 100 ); + idStr::snPrintf( lumpname, sizeof( lumpname ), "map0%i", map % 100 ); } else { - sprintf( lumpname, "map%i", map % 100 ); + idStr::snPrintf( lumpname, sizeof( lumpname ), "map%i", map % 100 ); } } else diff --git a/doomclassic/doom/st_stuff.cpp b/doomclassic/doom/st_stuff.cpp index e1562533..36a712bc 100644 --- a/doomclassic/doom/st_stuff.cpp +++ b/doomclassic/doom/st_stuff.cpp @@ -540,7 +540,7 @@ ST_Responder( event_t* ev ) else if( cht_CheckCheat( &cheat_mypos, ev->data1 ) ) { static char buf[ST_MSGWIDTH]; - sprintf( buf, "ang=0x%x;x,y=(0x%x,0x%x)", + idStr::snPrintf( buf, sizeof( buf ), "ang=0x%x;x,y=(0x%x,0x%x)", ::g->players[::g->consoleplayer].mo->angle, ::g->players[::g->consoleplayer].mo->x, ::g->players[::g->consoleplayer].mo->y ); @@ -1069,7 +1069,7 @@ void ST_loadGraphics( void ) // key cards for( i = 0; i < NUMCARDS; i++ ) { - sprintf( namebuf, "STKEYS%d", i ); + idStr::snPrintf( namebuf, sizeof( namebuf ), "STKEYS%d", i ); ::g->keys[i] = ( patch_t* ) W_CacheLumpName( namebuf, PU_STATIC_SHARED ); } @@ -1079,7 +1079,7 @@ void ST_loadGraphics( void ) // ::g->arms ownership widgets for( i = 0; i < 6; i++ ) { - sprintf( namebuf, "STGNUM%d", i + 2 ); + idStr::snPrintf( namebuf, sizeof( namebuf ), "STGNUM%d", i + 2 ); // gray # ::g->arms[i][0] = ( patch_t* ) W_CacheLumpName( namebuf, PU_STATIC_SHARED ); @@ -1089,7 +1089,7 @@ void ST_loadGraphics( void ) } // face backgrounds for different color ::g->players - sprintf( namebuf, "STFB%d", ::g->consoleplayer ); + idStr::snPrintf( namebuf, sizeof( namebuf ), "STFB%d", ::g->consoleplayer ); ::g->faceback = ( patch_t* ) W_CacheLumpName( namebuf, PU_STATIC_SHARED ); // status bar background bits @@ -1101,18 +1101,18 @@ void ST_loadGraphics( void ) { for( j = 0; j < ST_NUMSTRAIGHTFACES; j++ ) { - sprintf( namebuf, "STFST%d%d", i, j ); + idStr::snPrintf( namebuf, sizeof( namebuf ), "STFST%d%d", i, j ); ::g->faces[facenum++] = ( patch_t* )W_CacheLumpName( namebuf, PU_STATIC_SHARED ); } - sprintf( namebuf, "STFTR%d0", i ); // turn right + idStr::snPrintf( namebuf, sizeof( namebuf ), "STFTR%d0", i ); // turn right ::g->faces[facenum++] = ( patch_t* )W_CacheLumpName( namebuf, PU_STATIC_SHARED ); - sprintf( namebuf, "STFTL%d0", i ); // turn left + idStr::snPrintf( namebuf, sizeof( namebuf ), "STFTL%d0", i ); // turn left ::g->faces[facenum++] = ( patch_t* )W_CacheLumpName( namebuf, PU_STATIC_SHARED ); - sprintf( namebuf, "STFOUCH%d", i ); // ouch! + idStr::snPrintf( namebuf, sizeof( namebuf ), "STFOUCH%d", i ); // ouch! ::g->faces[facenum++] = ( patch_t* )W_CacheLumpName( namebuf, PU_STATIC_SHARED ); - sprintf( namebuf, "STFEVL%d", i ); // evil grin ;) + idStr::snPrintf( namebuf, sizeof( namebuf ), "STFEVL%d", i ); // evil grin ;) ::g->faces[facenum++] = ( patch_t* )W_CacheLumpName( namebuf, PU_STATIC_SHARED ); - sprintf( namebuf, "STFKILL%d", i ); // pissed off + idStr::snPrintf( namebuf, sizeof( namebuf ), "STFKILL%d", i ); // pissed off ::g->faces[facenum++] = ( patch_t* )W_CacheLumpName( namebuf, PU_STATIC_SHARED ); } ::g->faces[facenum++] = ( patch_t* )W_CacheLumpName( "STFGOD0", PU_STATIC_SHARED ); @@ -1516,7 +1516,7 @@ CONSOLE_COMMAND_SHIP( idmypos, "for player position", 0 ) } static char buf[ST_MSGWIDTH]; - sprintf( buf, "ang=0x%x;x,y=(0x%x,0x%x)", + idStr::snPrintf( buf, sizeof( buf ), "ang=0x%x;x,y=(0x%x,0x%x)", ::g->players[::g->consoleplayer].mo->angle, ::g->players[::g->consoleplayer].mo->x, ::g->players[::g->consoleplayer].mo->y ); diff --git a/doomclassic/doom/wi_stuff.cpp b/doomclassic/doom/wi_stuff.cpp index b9201acf..47146a61 100644 --- a/doomclassic/doom/wi_stuff.cpp +++ b/doomclassic/doom/wi_stuff.cpp @@ -1720,7 +1720,7 @@ void WI_loadData( void ) ::g->lnames = ( patch_t** ) DoomLib::Z_Malloc( sizeof( patch_t* ) * ( NUMMAPS ), PU_LEVEL_SHARED, 0 ); for( i = 0 ; i < NUMMAPS ; i++ ) { - sprintf( name, "WILV%d%d", ::g->wbs->epsd, i ); + idStr::snPrintf( name, sizeof( name ), "WILV%d%d", ::g->wbs->epsd, i ); ::g->lnames[i] = ( patch_t* )W_CacheLumpName( name, PU_LEVEL_SHARED ); } @@ -1763,7 +1763,7 @@ void WI_loadData( void ) for( i = 0; i < 10; i++ ) { // numbers 0-9 - sprintf( name, "WINUM%d", i ); + idStr::snPrintf( name, sizeof( name ), "WINUM%d", i ); ::g->num[i] = ( patch_t* )W_CacheLumpName( name, PU_LEVEL_SHARED ); } @@ -1820,11 +1820,11 @@ void WI_loadData( void ) for( i = 0 ; i < MAXPLAYERS ; i++ ) { // "1,2,3,4" - sprintf( name, "STPB%d", i ); + idStr::snPrintf( name, sizeof( name ), "STPB%d", i ); ::g->wistuff_p[i] = ( patch_t* )W_CacheLumpName( name, PU_LEVEL_SHARED ); // "1,2,3,4" - sprintf( name, "WIBP%d", i + 1 ); + idStr::snPrintf( name, sizeof( name ), "WIBP%d", i + 1 ); ::g->wistuff_bp[i] = ( patch_t* )W_CacheLumpName( name, PU_LEVEL_SHARED ); } diff --git a/neo/cm/CollisionModel_debug.cpp b/neo/cm/CollisionModel_debug.cpp index f3b060e4..bd774384 100644 --- a/neo/cm/CollisionModel_debug.cpp +++ b/neo/cm/CollisionModel_debug.cpp @@ -511,11 +511,11 @@ void idCollisionModelManagerLocal::DebugOutput( const idVec3& origin ) total_translation += t; if( cm_testTimes.GetInteger() > 9999 ) { - sprintf( buf, "%3dK", ( int )( cm_testTimes.GetInteger() / 1000 ) ); + idStr::snPrintf( buf, sizeof( buf ), "%3dK", ( int )( cm_testTimes.GetInteger() / 1000 ) ); } else { - sprintf( buf, "%4d", cm_testTimes.GetInteger() ); + idStr::snPrintf( buf, sizeof( buf ), "%4d", cm_testTimes.GetInteger() ); } common->Printf( "%s translations: %4d milliseconds, (min = %d, max = %d, av = %1.1f)\n", buf, t, min_translation, max_translation, ( float ) total_translation / num_translation ); @@ -571,11 +571,11 @@ void idCollisionModelManagerLocal::DebugOutput( const idVec3& origin ) total_rotation += t; if( cm_testTimes.GetInteger() > 9999 ) { - sprintf( buf, "%3dK", ( int )( cm_testTimes.GetInteger() / 1000 ) ); + idStr::snPrintf( buf, sizeof( buf ), "%3dK", ( int )( cm_testTimes.GetInteger() / 1000 ) ); } else { - sprintf( buf, "%4d", cm_testTimes.GetInteger() ); + idStr::snPrintf( buf, sizeof( buf ), "%4d", cm_testTimes.GetInteger() ); } common->Printf( "%s rotation: %4d milliseconds, (min = %d, max = %d, av = %1.1f)\n", buf, t, min_rotation, max_rotation, ( float ) total_rotation / num_rotation ); } diff --git a/neo/d3xp/MultiplayerGame.cpp b/neo/d3xp/MultiplayerGame.cpp index 0d48a32c..959fec89 100644 --- a/neo/d3xp/MultiplayerGame.cpp +++ b/neo/d3xp/MultiplayerGame.cpp @@ -653,7 +653,7 @@ const char* idMultiplayerGame::GameTime() } else { - sprintf( buff, "WMP %i", s ); + idStr::snPrintf( buff, sizeof( buff ), "WMP %i", s ); } } else diff --git a/neo/d3xp/Weapon.cpp b/neo/d3xp/Weapon.cpp index 1f343cae..45d2287d 100644 --- a/neo/d3xp/Weapon.cpp +++ b/neo/d3xp/Weapon.cpp @@ -3052,7 +3052,7 @@ const char* idWeapon::GetAmmoNameForNum( ammo_t ammonum ) return NULL; } - sprintf( text, "%d", ammonum ); + idStr::snPrintf( text, sizeof( text ), "%d", ammonum ); num = ammoDict->GetNumKeyVals(); for( i = 0; i < num; i++ ) diff --git a/neo/d3xp/gamesys/Event.cpp b/neo/d3xp/gamesys/Event.cpp index 22ff9028..80734c37 100644 --- a/neo/d3xp/gamesys/Event.cpp +++ b/neo/d3xp/gamesys/Event.cpp @@ -84,7 +84,7 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return if( numargs > D_EVENT_MAXARGS ) { eventError = true; - sprintf( eventErrorMsg, "idEventDef::idEventDef : Too many args for '%s' event.", name ); + idStr::snPrintf( eventErrorMsg, sizeof( eventErrorMsg ), "idEventDef::idEventDef : Too many args for '%s' event.", name ); return; } @@ -138,7 +138,7 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return default : eventError = true; - sprintf( eventErrorMsg, "idEventDef::idEventDef : Invalid arg format '%s' string for '%s' event.", formatspec, name ); + idStr::snPrintf( eventErrorMsg, sizeof( eventErrorMsg ), "idEventDef::idEventDef : Invalid arg format '%s' string for '%s' event.", formatspec, name ); return; break; } @@ -158,7 +158,7 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return if( strcmp( formatspec, ev->formatspec ) != 0 ) { eventError = true; - sprintf( eventErrorMsg, "idEvent '%s' defined twice with same name but differing format strings ('%s'!='%s').", + idStr::snPrintf( eventErrorMsg, sizeof( eventErrorMsg ), "idEvent '%s' defined twice with same name but differing format strings ('%s'!='%s').", command, formatspec, ev->formatspec ); return; } @@ -166,7 +166,7 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return if( ev->returnType != returnType ) { eventError = true; - sprintf( eventErrorMsg, "idEvent '%s' defined twice with same name but differing return types ('%c'!='%c').", + idStr::snPrintf( eventErrorMsg, sizeof( eventErrorMsg ), "idEvent '%s' defined twice with same name but differing return types ('%c'!='%c').", command, returnType, ev->returnType ); return; } @@ -181,7 +181,7 @@ idEventDef::idEventDef( const char* command, const char* formatspec, char return if( numEventDefs >= MAX_EVENTS ) { eventError = true; - sprintf( eventErrorMsg, "numEventDefs >= MAX_EVENTS" ); + idStr::snPrintf( eventErrorMsg, sizeof( eventErrorMsg ), "numEventDefs >= MAX_EVENTS" ); return; } eventDefList[numEventDefs] = ev; diff --git a/neo/d3xp/gamesys/SaveGame.cpp b/neo/d3xp/gamesys/SaveGame.cpp index 9a2e3d8a..9590e54a 100644 --- a/neo/d3xp/gamesys/SaveGame.cpp +++ b/neo/d3xp/gamesys/SaveGame.cpp @@ -1085,7 +1085,7 @@ void idRestoreGame::Error( const char* fmt, ... ) char text[ 1024 ]; va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); va_end( argptr ); objects.DeleteContents( true ); diff --git a/neo/d3xp/gamesys/SysCmds.cpp b/neo/d3xp/gamesys/SysCmds.cpp index ce39661c..a4dcdb55 100644 --- a/neo/d3xp/gamesys/SysCmds.cpp +++ b/neo/d3xp/gamesys/SysCmds.cpp @@ -1437,7 +1437,7 @@ static void PrintFloat( float f ) char buf[128]; int i; - for( i = sprintf( buf, "%3.2f", f ); i < 7; i++ ) + for( i = idStr::snPrintf( buf, sizeof( buf ), "%3.2f", f ); i < 7; i++ ) { buf[i] = ' '; } diff --git a/neo/d3xp/gamesys/SysCvar.cpp b/neo/d3xp/gamesys/SysCvar.cpp index e173df98..d2523d2b 100644 --- a/neo/d3xp/gamesys/SysCvar.cpp +++ b/neo/d3xp/gamesys/SysCvar.cpp @@ -43,7 +43,7 @@ All game cvars should be defined here. */ struct gameVersion_s { - gameVersion_s() { sprintf( string, "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); } + gameVersion_s() { idStr::snPrintf( string, sizeof( string ), "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); } char string[256]; } gameVersion; diff --git a/neo/d3xp/script/Script_Compiler.cpp b/neo/d3xp/script/Script_Compiler.cpp index 10ad1987..d6aa17c1 100644 --- a/neo/d3xp/script/Script_Compiler.cpp +++ b/neo/d3xp/script/Script_Compiler.cpp @@ -264,7 +264,7 @@ void idCompiler::Error( const char* message, ... ) const char string[ 1024 ]; va_start( argptr, message ); - vsprintf( string, message, argptr ); + idStr::vsnPrintf( string, sizeof( string ), message, argptr ); va_end( argptr ); #if defined(USE_EXCEPTIONS) @@ -287,7 +287,7 @@ void idCompiler::Warning( const char* message, ... ) const char string[ 1024 ]; va_start( argptr, message ); - vsprintf( string, message, argptr ); + idStr::vsnPrintf( string, sizeof( string ), message, argptr ); va_end( argptr ); parserPtr->Warning( "%s", string ); diff --git a/neo/d3xp/script/Script_Interpreter.cpp b/neo/d3xp/script/Script_Interpreter.cpp index f89c8c09..8c8d63da 100644 --- a/neo/d3xp/script/Script_Interpreter.cpp +++ b/neo/d3xp/script/Script_Interpreter.cpp @@ -504,7 +504,7 @@ void idInterpreter::Error( const char* fmt, ... ) const char text[ 1024 ]; va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); va_end( argptr ); StackTrace(); @@ -533,7 +533,7 @@ void idInterpreter::Warning( const char* fmt, ... ) const char text[ 1024 ]; va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); va_end( argptr ); if( ( instructionPointer >= 0 ) && ( instructionPointer < gameLocal.program.NumStatements() ) ) diff --git a/neo/d3xp/script/Script_Interpreter.h b/neo/d3xp/script/Script_Interpreter.h index 08064570..c2eb2f12 100644 --- a/neo/d3xp/script/Script_Interpreter.h +++ b/neo/d3xp/script/Script_Interpreter.h @@ -207,11 +207,11 @@ ID_INLINE const char* idInterpreter::FloatToString( float value ) if( value == ( float )( int )value ) { - sprintf( text, "%d", ( int )value ); + idStr::snPrintf( text, sizeof( text ), "%d", ( int )value ); } else { - sprintf( text, "%f", value ); + idStr::snPrintf( text, sizeof( text ), "%f", value ); } return text; } diff --git a/neo/d3xp/script/Script_Thread.cpp b/neo/d3xp/script/Script_Thread.cpp index e6af5d9f..eb93b4b3 100644 --- a/neo/d3xp/script/Script_Thread.cpp +++ b/neo/d3xp/script/Script_Thread.cpp @@ -892,7 +892,7 @@ void idThread::Error( const char* fmt, ... ) const char text[ 1024 ]; va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); va_end( argptr ); interpreter.Error( text ); @@ -909,7 +909,7 @@ void idThread::Warning( const char* fmt, ... ) const char text[ 1024 ]; va_start( argptr, fmt ); - vsprintf( text, fmt, argptr ); + idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); va_end( argptr ); interpreter.Warning( text ); diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp index 99b25dae..0db2ad7f 100644 --- a/neo/framework/Common.cpp +++ b/neo/framework/Common.cpp @@ -63,7 +63,7 @@ struct version_s { version_s() { - sprintf( string, "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); + idStr::snPrintf( string, sizeof( string ), "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); } char string[256]; } version; diff --git a/neo/framework/Common_printf.cpp b/neo/framework/Common_printf.cpp index f56e6144..ac2d0afe 100644 --- a/neo/framework/Common_printf.cpp +++ b/neo/framework/Common_printf.cpp @@ -125,11 +125,11 @@ void idCommonLocal::VPrintf( const char* fmt, va_list args ) int t = Sys_Milliseconds(); if( com_timestampPrints.GetInteger() == 1 ) { - sprintf( msg, "[%5.2f]", t * 0.001f ); + idStr::snPrintf( msg, sizeof( msg ), "[%5.2f]", t * 0.001f ); } else { - sprintf( msg, "[%i]", t ); + idStr::snPrintf( msg, sizeof( msg ), "[%i]", t ); } } timeLength = strlen( msg ); diff --git a/neo/framework/Console.cpp b/neo/framework/Console.cpp index d2455600..35e2dd43 100644 --- a/neo/framework/Console.cpp +++ b/neo/framework/Console.cpp @@ -200,6 +200,10 @@ void idConsoleLocal::DrawTextRightAlign( float x, float& y, const char* text, .. va_start( argptr, text ); int i = idStr::vsnPrintf( string, sizeof( string ), text, argptr ); va_end( argptr ); + if( i < 0 ) + { + i = sizeof( string ) - 1; + } renderSystem->DrawSmallStringExt( x - i * SMALLCHAR_WIDTH, y + 2, string, colorWhite, true ); y += SMALLCHAR_HEIGHT + 4; } diff --git a/neo/framework/DeclAF.cpp b/neo/framework/DeclAF.cpp index 6b83891f..f5369234 100644 --- a/neo/framework/DeclAF.cpp +++ b/neo/framework/DeclAF.cpp @@ -250,7 +250,7 @@ const char* idAFVector::ToString( idStr& str, const int precision ) case idAFVector::VEC_COORDS: { char format[128]; - sprintf( format, "( %%.%df, %%.%df, %%.%df )", precision, precision, precision ); + idStr::snPrintf( format, sizeof( format ), "( %%.%df, %%.%df, %%.%df )", precision, precision, precision ); sprintf( str, format, vec.x, vec.y, vec.z ); break; } diff --git a/neo/framework/DeclManager.cpp b/neo/framework/DeclManager.cpp index 1be49497..9938eab6 100644 --- a/neo/framework/DeclManager.cpp +++ b/neo/framework/DeclManager.cpp @@ -1757,7 +1757,7 @@ void idDeclManagerLocal::WritePrecacheCommands( idFile* f ) } char str[1024]; - sprintf( str, "touch %s %s\n", declTypes[i]->typeName.c_str(), decl->GetName() ); + idStr::snPrintf( str, sizeof( str ), "touch %s %s\n", declTypes[i]->typeName.c_str(), decl->GetName() ); common->Printf( "%s", str ); f->Printf( "%s", str ); } diff --git a/neo/framework/File.cpp b/neo/framework/File.cpp index 5b37455c..a5712d25 100644 --- a/neo/framework/File.cpp +++ b/neo/framework/File.cpp @@ -38,7 +38,7 @@ If you have questions concerning this license or the applicable additional terms FS_WriteFloatString ================= */ -int FS_WriteFloatString( char* buf, const char* fmt, va_list argPtr ) +int FS_WriteFloatString( char* buf, int bufsize, const char* fmt, va_list argPtr ) { // DG: replaced long with int for 64bit compatibility in the whole function int i; @@ -77,44 +77,44 @@ int FS_WriteFloatString( char* buf, const char* fmt, va_list argPtr ) sprintf( tmp, "%1.10f", f ); tmp.StripTrailing( '0' ); tmp.StripTrailing( '.' ); - index += sprintf( buf + index, "%s", tmp.c_str() ); + index += idStr::snPrintf( buf + index, bufsize - index, "%s", tmp.c_str() ); } else { - index += sprintf( buf + index, format.c_str(), f ); + index += idStr::snPrintf( buf + index, bufsize - index, format.c_str(), f ); } break; case 'd': case 'i': i = va_arg( argPtr, int ); - index += sprintf( buf + index, format.c_str(), i ); + index += idStr::snPrintf( buf + index, bufsize - index, format.c_str(), i ); break; case 'u': u = va_arg( argPtr, unsigned int ); - index += sprintf( buf + index, format.c_str(), u ); + index += idStr::snPrintf( buf + index, bufsize - index, format.c_str(), u ); break; case 'o': u = va_arg( argPtr, unsigned int ); - index += sprintf( buf + index, format.c_str(), u ); + index += idStr::snPrintf( buf + index, bufsize - index, format.c_str(), u ); break; case 'x': u = va_arg( argPtr, unsigned int ); - index += sprintf( buf + index, format.c_str(), u ); + index += idStr::snPrintf( buf + index, bufsize - index, format.c_str(), u ); break; case 'X': u = va_arg( argPtr, unsigned int ); - index += sprintf( buf + index, format.c_str(), u ); + index += idStr::snPrintf( buf + index, bufsize - index, format.c_str(), u ); break; case 'c': i = va_arg( argPtr, int ); - index += sprintf( buf + index, format.c_str(), ( char ) i ); + index += idStr::snPrintf( buf + index, bufsize - index, format.c_str(), ( char ) i ); break; case 's': str = va_arg( argPtr, char* ); - index += sprintf( buf + index, format.c_str(), str ); + index += idStr::snPrintf( buf + index, bufsize - index, format.c_str(), str ); break; case '%': - index += sprintf( buf + index, "%s", format.c_str() ); + index += idStr::snPrintf( buf + index, bufsize - index, "%s", format.c_str() ); break; default: common->Error( "FS_WriteFloatString: invalid format %s", format.c_str() ); @@ -127,16 +127,16 @@ int FS_WriteFloatString( char* buf, const char* fmt, va_list argPtr ) switch( *fmt ) { case 't': - index += sprintf( buf + index, "\t" ); + index += idStr::snPrintf( buf + index, bufsize - index, "\t" ); break; case 'v': - index += sprintf( buf + index, "\v" ); + index += idStr::snPrintf( buf + index, bufsize - index, "\v" ); break; case 'n': - index += sprintf( buf + index, "\n" ); + index += idStr::snPrintf( buf + index, bufsize - index, "\n" ); break; case '\\': - index += sprintf( buf + index, "\\" ); + index += idStr::snPrintf( buf + index, bufsize - index, "\\" ); break; default: common->Error( "FS_WriteFloatString: unknown escape character \'%c\'", *fmt ); @@ -145,7 +145,7 @@ int FS_WriteFloatString( char* buf, const char* fmt, va_list argPtr ) fmt++; break; default: - index += sprintf( buf + index, "%c", *fmt ); + index += idStr::snPrintf( buf + index, bufsize - index, "%c", *fmt ); fmt++; break; } @@ -285,7 +285,7 @@ int idFile::Printf( const char* fmt, ... ) va_list argptr; va_start( argptr, fmt ); - length = idStr::vsnPrintf( buf, MAX_PRINT_MSG - 1, fmt, argptr ); + length = idStr::vsnPrintf( buf, sizeof( buf ), fmt, argptr ); va_end( argptr ); // so notepad formats the lines correctly @@ -305,7 +305,11 @@ int idFile::VPrintf( const char* fmt, va_list args ) char buf[MAX_PRINT_MSG]; int length; - length = idStr::vsnPrintf( buf, MAX_PRINT_MSG - 1, fmt, args ); + length = idStr::vsnPrintf( buf, sizeof( buf ), fmt, args ); + if( length < 0 ) + { + length = sizeof( buf ) - 1; + } return Write( buf, length ); } @@ -321,7 +325,7 @@ int idFile::WriteFloatString( const char* fmt, ... ) va_list argPtr; va_start( argPtr, fmt ); - len = FS_WriteFloatString( buf, fmt, argPtr ); + len = FS_WriteFloatString( buf, sizeof( buf ), fmt, argPtr ); va_end( argPtr ); return Write( buf, len ); diff --git a/neo/framework/TokenParser.cpp b/neo/framework/TokenParser.cpp index 98b5d118..2ccc3dbc 100644 --- a/neo/framework/TokenParser.cpp +++ b/neo/framework/TokenParser.cpp @@ -252,7 +252,7 @@ void idTokenParser::Error( VERIFY_FORMAT_STRING const char* str, ... ) va_list ap; va_start( ap, str ); - vsprintf( text, str, ap ); + idStr::vsnPrintf( text, sizeof( text ), str, ap ); va_end( ap ); idLib::common->Warning( text ); @@ -263,7 +263,7 @@ void idTokenParser::Warning( VERIFY_FORMAT_STRING const char* str, ... ) va_list ap; va_start( ap, str ); - vsprintf( text, str, ap ); + idStr::vsnPrintf( text, sizeof( text ), str, ap ); va_end( ap ); idLib::common->Warning( text ); diff --git a/neo/idlib/Lexer.cpp b/neo/idlib/Lexer.cpp index 20eb2a1b..72b28bc4 100644 --- a/neo/idlib/Lexer.cpp +++ b/neo/idlib/Lexer.cpp @@ -247,7 +247,7 @@ void idLexer::Error( const char* str, ... ) } va_start( ap, str ); - vsprintf( text, str, ap ); + idStr::vsnPrintf( text, sizeof( text ), str, ap ); va_end( ap ); if( idLexer::flags & LEXFL_NOFATALERRORS ) @@ -276,7 +276,7 @@ void idLexer::Warning( const char* str, ... ) } va_start( ap, str ); - vsprintf( text, str, ap ); + idStr::vsnPrintf( text, sizeof( text ), str, ap ); va_end( ap ); idLib::common->Warning( "file %s, line %d: %s", idLexer::filename.c_str(), idLexer::line, text ); } diff --git a/neo/idlib/Parser.cpp b/neo/idlib/Parser.cpp index c1cd53a7..d61dd535 100644 --- a/neo/idlib/Parser.cpp +++ b/neo/idlib/Parser.cpp @@ -367,7 +367,7 @@ void idParser::Error( const char* str, ... ) const va_list ap; va_start( ap, str ); - vsprintf( text, str, ap ); + idStr::vsnPrintf( text, sizeof( text ), str, ap ); va_end( ap ); if( idParser::scriptstack ) { @@ -386,7 +386,7 @@ void idParser::Warning( const char* str, ... ) const va_list ap; va_start( ap, str ); - vsprintf( text, str, ap ); + idStr::vsnPrintf( text, sizeof( text ), str, ap ); va_end( ap ); if( idParser::scriptstack ) { @@ -836,7 +836,7 @@ int idParser::ExpandBuiltinDefine( idToken* deftoken, define_t* define, idToken* { case BUILTIN_LINE: { - sprintf( buf, "%d", deftoken->line ); + idStr::snPrintf( buf, sizeof( buf ), "%d", deftoken->line ); ( *token ) = buf; token->intvalue = deftoken->line; token->floatvalue = deftoken->line; @@ -2680,7 +2680,7 @@ int idParser::Directive_eval() token.whiteSpaceEnd_p = NULL; token.linesCrossed = 0; token.flags = 0; - sprintf( buf, "%d", abs( value ) ); + idStr::snPrintf( buf, sizeof( buf ), "%d", abs( value ) ); token = buf; token.type = TT_NUMBER; token.subtype = TT_INTEGER | TT_LONG | TT_DECIMAL; @@ -2713,7 +2713,7 @@ int idParser::Directive_evalfloat() token.whiteSpaceEnd_p = NULL; token.linesCrossed = 0; token.flags = 0; - sprintf( buf, "%1.2f", idMath::Fabs( value ) ); + idStr::snPrintf( buf, sizeof( buf ), "%1.2f", idMath::Fabs( value ) ); token = buf; token.type = TT_NUMBER; token.subtype = TT_FLOAT | TT_LONG | TT_DECIMAL; @@ -2850,7 +2850,7 @@ int idParser::DollarDirective_evalint() token.whiteSpaceEnd_p = NULL; token.linesCrossed = 0; token.flags = 0; - sprintf( buf, "%d", abs( value ) ); + idStr::snPrintf( buf, sizeof( buf ), "%d", abs( value ) ); token = buf; token.type = TT_NUMBER; token.subtype = TT_INTEGER | TT_LONG | TT_DECIMAL | TT_VALUESVALID; @@ -2885,7 +2885,7 @@ int idParser::DollarDirective_evalfloat() token.whiteSpaceEnd_p = NULL; token.linesCrossed = 0; token.flags = 0; - sprintf( buf, "%1.2f", fabs( value ) ); + idStr::snPrintf( buf, sizeof( buf ), "%1.2f", fabs( value ) ); token = buf; token.type = TT_NUMBER; token.subtype = TT_FLOAT | TT_LONG | TT_DECIMAL | TT_VALUESVALID; diff --git a/neo/idlib/Str.cpp b/neo/idlib/Str.cpp index 3269bd31..bc121cd5 100644 --- a/neo/idlib/Str.cpp +++ b/neo/idlib/Str.cpp @@ -734,11 +734,11 @@ void idStr::Format( const char* fmt, ... ) char text[MAX_PRINT_MSG]; va_start( argptr, fmt ); - int len = idStr::vsnPrintf( text, sizeof( text ) - 1, fmt, argptr ); + // SRS - using idStr::vsnPrintf() guarantees size and null termination + int len = idStr::vsnPrintf( text, sizeof( text ), fmt, argptr ); va_end( argptr ); - text[ sizeof( text ) - 1 ] = '\0'; - if( ( size_t )len >= sizeof( text ) - 1 ) + if( len < 0 ) { idLib::common->FatalError( "Tried to set a large buffer using %s", fmt ); } @@ -2247,21 +2247,16 @@ int idStr::snPrintf( char* dest, int size, const char* fmt, ... ) { int len; va_list argptr; - char buffer[32000]; // big, but small enough to fit in PPC stack va_start( argptr, fmt ); - len = vsprintf( buffer, fmt, argptr ); + // SRS - using idStr::vsnPrintf() guarantees size and null termination + len = idStr::vsnPrintf( dest, size, fmt, argptr ); va_end( argptr ); - if( len >= sizeof( buffer ) ) + if( len < 0 ) { - idLib::common->Error( "idStr::snPrintf: overflowed buffer" ); + idLib::common->Warning( "idStr::snPrintf: overflow of %i in %i\n", len, size - 1 ); + len = size - 1; } - if( len >= size ) - { - idLib::common->Warning( "idStr::snPrintf: overflow of %i in %i\n", len, size ); - len = size; - } - idStr::Copynz( dest, buffer, size ); return len; } @@ -2321,9 +2316,13 @@ int sprintf( idStr& string, const char* fmt, ... ) char buffer[32000]; va_start( argptr, fmt ); - l = idStr::vsnPrintf( buffer, sizeof( buffer ) - 1, fmt, argptr ); + // SRS - using idStr::vsnPrintf() guarantees size and null termination + l = idStr::vsnPrintf( buffer, sizeof( buffer ), fmt, argptr ); va_end( argptr ); - buffer[sizeof( buffer ) - 1] = '\0'; + if( l < 0 ) + { + l = sizeof( buffer ) - 1; + } string = buffer; return l; @@ -2341,8 +2340,12 @@ int vsprintf( idStr& string, const char* fmt, va_list argptr ) int l; char buffer[32000]; - l = idStr::vsnPrintf( buffer, sizeof( buffer ) - 1, fmt, argptr ); - buffer[sizeof( buffer ) - 1] = '\0'; + // SRS - using idStr::vsnPrintf() guarantees size and null termination + l = idStr::vsnPrintf( buffer, sizeof( buffer ), fmt, argptr ); + if( l < 0 ) + { + l = sizeof( buffer ) - 1; + } string = buffer; return l; @@ -2364,12 +2367,14 @@ char* va( const char* fmt, ... ) char* buf; buf = string[index]; - index = ( index + 1 ) & 3; va_start( argptr, fmt ); - vsprintf( buf, fmt, argptr ); + // SRS - using idStr::vsnPrintf() guarantees size and null termination + idStr::vsnPrintf( buf, sizeof( string[index] ), fmt, argptr ); va_end( argptr ); + index = ( index + 1 ) & 3; + return buf; } diff --git a/neo/idlib/Str.h b/neo/idlib/Str.h index b39b5c8d..3321c275 100644 --- a/neo/idlib/Str.h +++ b/neo/idlib/Str.h @@ -610,7 +610,7 @@ ID_INLINE idStr::idStr( const int i ) char text[ 64 ]; int l; - l = sprintf( text, "%d", i ); + l = idStr::snPrintf( text, sizeof( text ), "%d", i ); EnsureAlloced( l + 1 ); strcpy( data, text ); len = l; @@ -622,7 +622,7 @@ ID_INLINE idStr::idStr( const unsigned u ) char text[ 64 ]; int l; - l = sprintf( text, "%u", u ); + l = idStr::snPrintf( text, sizeof( text ), "%u", u ); EnsureAlloced( l + 1 ); strcpy( data, text ); len = l; @@ -758,7 +758,7 @@ ID_INLINE idStr operator+( const idStr& a, const float b ) char text[ 64 ]; idStr result( a ); - sprintf( text, "%f", b ); + idStr::snPrintf( text, sizeof( text ), "%f", b ); result.Append( text ); return result; @@ -769,7 +769,7 @@ ID_INLINE idStr operator+( const idStr& a, const int b ) char text[ 64 ]; idStr result( a ); - sprintf( text, "%d", b ); + idStr::snPrintf( text, sizeof( text ), "%d", b ); result.Append( text ); return result; @@ -780,7 +780,7 @@ ID_INLINE idStr operator+( const idStr& a, const unsigned b ) char text[ 64 ]; idStr result( a ); - sprintf( text, "%u", b ); + idStr::snPrintf( text, sizeof( text ), "%u", b ); result.Append( text ); return result; @@ -790,7 +790,7 @@ ID_INLINE idStr& idStr::operator+=( const float a ) { char text[ 64 ]; - sprintf( text, "%f", a ); + idStr::snPrintf( text, sizeof( text ), "%f", a ); Append( text ); return *this; @@ -800,7 +800,7 @@ ID_INLINE idStr& idStr::operator+=( const int a ) { char text[ 64 ]; - sprintf( text, "%d", a ); + idStr::snPrintf( text, sizeof( text ), "%d", a ); Append( text ); return *this; @@ -810,7 +810,7 @@ ID_INLINE idStr& idStr::operator+=( const unsigned a ) { char text[ 64 ]; - sprintf( text, "%u", a ); + idStr::snPrintf( text, sizeof( text ), "%u", a ); Append( text ); return *this; diff --git a/neo/renderer/ImageManager.cpp b/neo/renderer/ImageManager.cpp index 86a75bea..f5fc8ae8 100644 --- a/neo/renderer/ImageManager.cpp +++ b/neo/renderer/ImageManager.cpp @@ -685,7 +685,7 @@ void R_CombineCubeImages_f( const idCmdArgs& args ) int orderRemap[6] = { 1, 3, 4, 2, 5, 6 }; for( side = 0 ; side < 6 ; side++ ) { - sprintf( filename, "%s%i%04i.tga", baseName.c_str(), orderRemap[side], frameNum ); + idStr::snPrintf( filename, sizeof( filename ), "%s%i%04i.tga", baseName.c_str(), orderRemap[side], frameNum ); idLib::Printf( "reading %s\n", filename ); R_LoadImage( filename, &pics[side], &width, &height, NULL, true, NULL ); @@ -738,7 +738,7 @@ void R_CombineCubeImages_f( const idCmdArgs& args ) memcpy( combined + width * height * 4 * side, pics[side], width * height * 4 ); Mem_Free( pics[side] ); } - sprintf( filename, "%sCM%04i.tga", baseName.c_str(), frameNum ); + idStr::snPrintf( filename, sizeof( filename ), "%sCM%04i.tga", baseName.c_str(), frameNum ); idLib::Printf( "writing %s\n", filename ); R_WriteTGA( filename, combined, width, height * 6 ); diff --git a/neo/renderer/Image_files.cpp b/neo/renderer/Image_files.cpp index 2fccdb30..c0035977 100644 --- a/neo/renderer/Image_files.cpp +++ b/neo/renderer/Image_files.cpp @@ -73,7 +73,7 @@ void jpg_Error( const char* fmt, ... ) char msg[2048]; va_start( argptr, fmt ); - vsprintf( msg, fmt, argptr ); + idStr::vsnPrintf( msg, sizeof( msg ), fmt, argptr ); va_end( argptr ); common->FatalError( "%s", msg ); @@ -85,7 +85,7 @@ void jpg_Printf( const char* fmt, ... ) char msg[2048]; va_start( argptr, fmt ); - vsprintf( msg, fmt, argptr ); + idStr::vsnPrintf( msg, sizeof( msg ), fmt, argptr ); va_end( argptr ); common->Printf( "%s", msg ); diff --git a/neo/renderer/ModelManager.cpp b/neo/renderer/ModelManager.cpp index 5b035d93..0a0e89fa 100644 --- a/neo/renderer/ModelManager.cpp +++ b/neo/renderer/ModelManager.cpp @@ -228,7 +228,7 @@ void idRenderModelManagerLocal::WritePrecacheCommands( idFile* f ) } char str[1024]; - sprintf( str, "touchModel %s\n", model->Name() ); + idStr::snPrintf( str, sizeof( str ), "touchModel %s\n", model->Name() ); common->Printf( "%s", str ); f->Printf( "%s", str ); } diff --git a/neo/sys/sdl/sdl_cpu.cpp b/neo/sys/sdl/sdl_cpu.cpp index 4e3bfa23..e9055742 100644 --- a/neo/sys/sdl/sdl_cpu.cpp +++ b/neo/sys/sdl/sdl_cpu.cpp @@ -305,11 +305,11 @@ static bitFlag_t statusWordFlags[] = Sys_FPU_PrintStateFlags =============== */ -int Sys_FPU_PrintStateFlags( char* ptr, int ctrl, int stat, int tags, int inof, int inse, int opof, int opse ) +int Sys_FPU_PrintStateFlags( char* buf, int bufsize, int ctrl, int stat, int tags, int inof, int inse, int opof, int opse ) { int i, length = 0; - length += sprintf( ptr + length, "CTRL = %08x\n" + length += idStr::snPrintf( buf + length, bufsize - length, "CTRL = %08x\n" "STAT = %08x\n" "TAGS = %08x\n" "INOF = %08x\n" @@ -319,21 +319,21 @@ int Sys_FPU_PrintStateFlags( char* ptr, int ctrl, int stat, int tags, int inof, "\n", ctrl, stat, tags, inof, inse, opof, opse ); - length += sprintf( ptr + length, "Control Word:\n" ); + length += idStr::snPrintf( buf + length, bufsize - length, "Control Word:\n" ); for( i = 0; controlWordFlags[i].name[0]; i++ ) { - length += sprintf( ptr + length, " %-30s = %s\n", controlWordFlags[i].name, ( ctrl & ( 1 << controlWordFlags[i].bit ) ) ? "true" : "false" ); + length += idStr::snPrintf( buf + length, bufsize - length, " %-30s = %s\n", controlWordFlags[i].name, ( ctrl & ( 1 << controlWordFlags[i].bit ) ) ? "true" : "false" ); } - length += sprintf( ptr + length, " %-30s = %s\n", "Precision control", precisionControlField[( ctrl >> 8 ) & 3] ); - length += sprintf( ptr + length, " %-30s = %s\n", "Rounding control", roundingControlField[( ctrl >> 10 ) & 3] ); + length += idStr::snPrintf( buf + length, bufsize - length, " %-30s = %s\n", "Precision control", precisionControlField[( ctrl >> 8 ) & 3] ); + length += idStr::snPrintf( buf + length, bufsize - length, " %-30s = %s\n", "Rounding control", roundingControlField[( ctrl >> 10 ) & 3] ); - length += sprintf( ptr + length, "Status Word:\n" ); + length += idStr::snPrintf( buf + length, bufsize - length, "Status Word:\n" ); for( i = 0; statusWordFlags[i].name[0]; i++ ) { - ptr += sprintf( ptr + length, " %-30s = %s\n", statusWordFlags[i].name, ( stat & ( 1 << statusWordFlags[i].bit ) ) ? "true" : "false" ); + length += idStr::snPrintf( buf + length, bufsize - length, " %-30s = %s\n", statusWordFlags[i].name, ( stat & ( 1 << statusWordFlags[i].bit ) ) ? "true" : "false" ); } - length += sprintf( ptr + length, " %-30s = %d%d%d%d\n", "Condition code", ( stat >> 8 ) & 1, ( stat >> 9 ) & 1, ( stat >> 10 ) & 1, ( stat >> 14 ) & 1 ); - length += sprintf( ptr + length, " %-30s = %d\n", "Top of stack pointer", ( stat >> 11 ) & 7 ); + length += idStr::snPrintf( buf + length, bufsize - length, " %-30s = %d%d%d%d\n", "Condition code", ( stat >> 8 ) & 1, ( stat >> 9 ) & 1, ( stat >> 10 ) & 1, ( stat >> 14 ) & 1 ); + length += idStr::snPrintf( buf + length, bufsize - length, " %-30s = %d\n", "Top of stack pointer", ( stat >> 11 ) & 7 ); return length; } diff --git a/neo/sys/sys_local.cpp b/neo/sys/sys_local.cpp index 4c4f8c16..bbfd0fc7 100644 --- a/neo/sys/sys_local.cpp +++ b/neo/sys/sys_local.cpp @@ -248,15 +248,15 @@ const char* Sys_SecToStr( int sec ) if( weeks > 0 ) { - sprintf( timeString, "%dw, %dd, %d:%02d:%02d", weeks, days, hours, min, sec ); + idStr::snPrintf( timeString, sizeof( timeString ), "%dw, %dd, %d:%02d:%02d", weeks, days, hours, min, sec ); } else if( days > 0 ) { - sprintf( timeString, "%dd, %d:%02d:%02d", days, hours, min, sec ); + idStr::snPrintf( timeString, sizeof( timeString ), "%dd, %d:%02d:%02d", days, hours, min, sec ); } else { - sprintf( timeString, "%d:%02d:%02d", hours, min, sec ); + idStr::snPrintf( timeString, sizeof( timeString ), "%d:%02d:%02d", hours, min, sec ); } return timeString; diff --git a/neo/sys/sys_session_local.cpp b/neo/sys/sys_session_local.cpp index 8d83e975..345ff3b1 100644 --- a/neo/sys/sys_session_local.cpp +++ b/neo/sys/sys_session_local.cpp @@ -89,7 +89,7 @@ struct netVersion_s { netVersion_s() { - sprintf( string, "%s.%d", ENGINE_VERSION, BUILD_NUMBER ); + idStr::snPrintf( string, sizeof( string ), "%s.%d", ENGINE_VERSION, BUILD_NUMBER ); } char string[256]; } netVersion; diff --git a/neo/tools/compilers/aas/Brush.cpp b/neo/tools/compilers/aas/Brush.cpp index 0f7e2ac6..aecd19c1 100644 --- a/neo/tools/compilers/aas/Brush.cpp +++ b/neo/tools/compilers/aas/Brush.cpp @@ -55,7 +55,7 @@ void DisplayRealTimeString( const char* string, ... ) if( time > lastUpdateTime + OUTPUT_UPDATE_TIME ) { va_start( argPtr, string ); - vsprintf( buf, string, argPtr ); + idStr::vsnPrintf( buf, sizeof( buf ), string, argPtr ); va_end( argPtr ); common->Printf( buf ); lastUpdateTime = time; diff --git a/neo/ui/DeviceContext.cpp b/neo/ui/DeviceContext.cpp index ac4b2ef3..04272d51 100644 --- a/neo/ui/DeviceContext.cpp +++ b/neo/ui/DeviceContext.cpp @@ -1005,9 +1005,10 @@ char* idRectangle::String() const // use an array so that multiple toString's won't collide s = str[ index ]; - index = ( index + 1 ) & 7; - sprintf( s, "%.2f %.2f %.2f %.2f", x, y, w, h ); + idStr::snPrintf( s, sizeof( str[ index ] ), "%.2f %.2f %.2f %.2f", x, y, w, h ); + + index = ( index + 1 ) & 7; return s; } diff --git a/neo/ui/UserInterface.cpp b/neo/ui/UserInterface.cpp index ab4a334c..eb4eb179 100644 --- a/neo/ui/UserInterface.cpp +++ b/neo/ui/UserInterface.cpp @@ -110,7 +110,7 @@ void idUserInterfaceManagerLocal::WritePrecacheCommands( idFile* f ) for( int i = 0; i < c; i++ ) { char str[1024]; - sprintf( str, "touchGui %s\n", guis[i]->Name() ); + idStr::snPrintf( str, sizeof( str ), "touchGui %s\n", guis[i]->Name() ); common->Printf( "%s", str ); f->Printf( "%s", str ); } diff --git a/neo/ui/Window.cpp b/neo/ui/Window.cpp index 9a6cccc6..c81df077 100644 --- a/neo/ui/Window.cpp +++ b/neo/ui/Window.cpp @@ -1138,16 +1138,16 @@ void idWindow::DebugDraw( int time, float x, float y ) if( str.Length() ) { - sprintf( buff, "%s\n", str.c_str() ); + idStr::snPrintf( buff, sizeof( buff ), "%s\n", str.c_str() ); } - sprintf( out, "Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", rect.x(), rect.y(), rect.w(), rect.h() ); + idStr::snPrintf( out, sizeof( out ), "Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", rect.x(), rect.y(), rect.w(), rect.h() ); strcat( buff, out ); - sprintf( out, "Draw Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", drawRect.x, drawRect.y, drawRect.w, drawRect.h ); + idStr::snPrintf( out, sizeof( out ), "Draw Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", drawRect.x, drawRect.y, drawRect.w, drawRect.h ); strcat( buff, out ); - sprintf( out, "Client Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", clientRect.x, clientRect.y, clientRect.w, clientRect.h ); + idStr::snPrintf( out, sizeof( out ), "Client Rect: %0.1f, %0.1f, %0.1f, %0.1f\n", clientRect.x, clientRect.y, clientRect.w, clientRect.h ); strcat( buff, out ); - sprintf( out, "Cursor: %0.1f : %0.1f\n", gui->CursorX(), gui->CursorY() ); + idStr::snPrintf( out, sizeof( out ), "Cursor: %0.1f : %0.1f\n", gui->CursorX(), gui->CursorY() ); strcat( buff, out );