From fb4106919514eea7bb3930748ab25cb9684f42fb Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Fri, 11 Sep 2026 08:06:59 +0200 Subject: [PATCH] Replace wsprintf with snprintf and a destination size --- code/display.cpp | 2 +- code/house.cpp | 8 ++++---- code/init.cpp | 10 +++++----- code/loaddlg.cpp | 2 +- code/netdlg2.cpp | 6 +++--- code/scenario.cpp | 10 +++++----- code/startup.cpp | 2 +- code/stats.cpp | 2 +- code/tagtype.cpp | 4 ++-- code/tevent.cpp | 15 ++++++++++----- code/tevent.h | 4 +++- code/trigtype.cpp | 2 +- code/waypoint.cpp | 4 ++-- code/winfix.cpp | 12 ++++++------ 14 files changed, 45 insertions(+), 38 deletions(-) diff --git a/code/display.cpp b/code/display.cpp index b9775bef5..1ad38d1b2 100644 --- a/code/display.cpp +++ b/code/display.cpp @@ -3383,7 +3383,7 @@ void DisplayClass::Write_INI(CCINIClass & ini) /* ** Generate entry name. */ - wsprintf(entry, "%d", x + (y * 1000)); + snprintf(entry, sizeof(entry), "%d", x + (y * 1000)); /* ** Save entry. diff --git a/code/house.cpp b/code/house.cpp index a1bf5b687..7074f06e3 100644 --- a/code/house.cpp +++ b/code/house.cpp @@ -2188,7 +2188,7 @@ void HouseClass::Make_Ally(HouseClass * house) } if (Is_Human_Player() && Session.Type != GAME_NORMAL && !house->Class->IsMultiplayPassive) { - wsprintf(buffer, Fetch_String(TXT_HAS_ALLIED), (char const *)IniName, (char const *)house->IniName); + snprintf(buffer, sizeof(buffer), Fetch_String(TXT_HAS_ALLIED), (char const *)IniName, (char const *)house->IniName); Session.Messages.Add_Message(NULL, 0, buffer, Class->Scheme, TextPrintType(TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW), int(TICKS_PER_MINUTE * Rule->MessageDelay)); if (Is_Player_Control()) { @@ -2261,7 +2261,7 @@ void HouseClass::Make_Enemy(HouseClass * house) if (Session.Type != GAME_NORMAL && !ScenarioInit && IsHuman) { char buffer[80]; - wsprintf(buffer, Fetch_String(TXT_AT_WAR), (char const *)IniName, (char const *)house->IniName); + snprintf(buffer, sizeof(buffer), Fetch_String(TXT_AT_WAR), (char const *)IniName, (char const *)house->IniName); Session.Messages.Add_Message(NULL, 0, buffer, Class->Scheme, TextPrintType(TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW), int(TICKS_PER_MINUTE * Rule->MessageDelay)); Map.Flag_To_Redraw(); if (Is_Player_Control()) { @@ -3315,7 +3315,7 @@ void HouseClass::MPlayer_Defeated(void) /* ** Pop up a message showing that I was defeated */ - wsprintf(txt, Fetch_String(TXT_PLAYER_DEFEATED), (char const *)IniName); + snprintf(txt, sizeof(txt), Fetch_String(TXT_PLAYER_DEFEATED), (char const *)IniName); Session.Messages.Add_Message(NULL, 0, txt, Session.ColorIdx, TextPrintType(TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW), int(Rule->MessageDelay * TICKS_PER_MINUTE)); @@ -3329,7 +3329,7 @@ void HouseClass::MPlayer_Defeated(void) ** If it wasn't me, find out who was defeated */ if (!Class->IsMultiplayPassive) { - wsprintf(txt, Fetch_String(TXT_PLAYER_DEFEATED), (char const *)IniName); + snprintf(txt, sizeof(txt), Fetch_String(TXT_PLAYER_DEFEATED), (char const *)IniName); Session.Messages.Add_Message(NULL, 0, txt, Scheme, TextPrintType(TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_FULLSHADOW), int(Rule->MessageDelay * TICKS_PER_MINUTE)); diff --git a/code/init.cpp b/code/init.cpp index a6994a892..aaccf5c27 100644 --- a/code/init.cpp +++ b/code/init.cpp @@ -6182,9 +6182,9 @@ void Init_Theater(TheaterType theater) /* ** Unload old mixfiles, and cache the new ones */ - wsprintf(fullname, "%s.MIX", data.Root.c_str()); - wsprintf(isofullname, "%s.MIX", data.IsoRoot.c_str()); - wsprintf(shortname, "%s.MIX", data.Suffix.c_str()); + snprintf(fullname, sizeof(fullname), "%s.MIX", data.Root.c_str()); + snprintf(isofullname, sizeof(isofullname), "%s.MIX", data.IsoRoot.c_str()); + snprintf(shortname, sizeof(shortname), "%s.MIX", data.Suffix.c_str()); DebugString("Init theater %s\n", data.Name()); @@ -6220,7 +6220,7 @@ void Init_Theater(TheaterType theater) ** Load the custom palette associated with this theater. ** The fading palettes will have to be generated as well. */ - wsprintf(fullname, "%s.PAL", data.Root.c_str()); + snprintf(fullname, sizeof(fullname), "%s.PAL", data.Root.c_str()); unsigned char * ptr = (unsigned char *)MFCD::Retrieve(fullname); @@ -6244,7 +6244,7 @@ void Init_Theater(TheaterType theater) if (!data.Suffix.empty()) { char palname[_MAX_PATH]; - wsprintf(palname, "UNIT%s.PAL", data.Suffix.c_str()); + snprintf(palname, sizeof(palname), "UNIT%s.PAL", data.Suffix.c_str()); unitpal = (PaletteClass *)MFCD::Retrieve(palname); } diff --git a/code/loaddlg.cpp b/code/loaddlg.cpp index 7d5467f38..164a00f2d 100644 --- a/code/loaddlg.cpp +++ b/code/loaddlg.cpp @@ -940,7 +940,7 @@ bool LoadOptionsClass::Read_File(FileEntryClass * fdata, WIN32_FIND_DATAA * ff) return(false); } - wsprintf(fdata->Descr, "%s", savever.Get_Scenario_Description()); + snprintf(fdata->Descr, sizeof(fdata->Descr), "%s", savever.Get_Scenario_Description()); fdata->Valid = ok; fdata->Scenario = savever.Get_Scenario_Number(); diff --git a/code/netdlg2.cpp b/code/netdlg2.cpp index abd5ef0b5..1423f7df4 100644 --- a/code/netdlg2.cpp +++ b/code/netdlg2.cpp @@ -2418,12 +2418,12 @@ static void Get_Join_Responses(void) //............................................................ if (JoinState < JOIN_CONFIRMED) { if (Session.Games[i]->Game.IsOpen) { - wsprintf(txt,Fetch_String(TXT_S_FORMED_NEW_GAME), + snprintf(txt, sizeof(txt), Fetch_String(TXT_S_FORMED_NEW_GAME), Session.GPacket.Name); Sound_Effect(Rule->GameForming); } else { - wsprintf(txt,Fetch_String(TXT_GAME_NOW_IN_PROGRESS), + snprintf(txt, sizeof(txt), Fetch_String(TXT_GAME_NOW_IN_PROGRESS), Session.GPacket.Name); Sound_Effect(Rule->GameClosed); } @@ -2466,7 +2466,7 @@ static void Get_Join_Responses(void) // now available. //.................................................................. if (Session.GPacket.GameInfo.IsOpen && JoinState < JOIN_CONFIRMED) { - wsprintf(txt,Fetch_String(TXT_S_FORMED_NEW_GAME), + snprintf(txt, sizeof(txt), Fetch_String(TXT_S_FORMED_NEW_GAME), Session.GPacket.Name); PMessagePrintf(ColorSystem, txt); Sound_Effect(Rule->GameForming); diff --git a/code/scenario.cpp b/code/scenario.cpp index 7019c5fc8..bfcc1ddf8 100644 --- a/code/scenario.cpp +++ b/code/scenario.cpp @@ -389,7 +389,7 @@ bool Start_Scenario(char const * name, bool briefing, CampaignType campaign) bool has_briefing_movie = Scen->BriefMovie != VQ_NONE; if (has_briefing_movie) { - wsprintf(buffer, "%s.VQA", Movies[Scen->BriefMovie]); + snprintf(buffer, sizeof(buffer), "%s.VQA", Movies[Scen->BriefMovie]); has_briefing_movie = CCFileClass(buffer).Is_Available(); } @@ -3733,8 +3733,8 @@ bool ScenarioClass::Write_Local_INI(CCINIClass & ini) const int length = ARRAY_SIZE(LocalFlags); for (int index = 0; index < length; index++) { if (LocalFlags[index].VariableName[0] != '\0') { - wsprintf(index_buffer, "%d", index); - wsprintf(buffer, "%s,%d", LocalFlags[index].VariableName, LocalFlags[index].Value ? 1 : 0); + snprintf(index_buffer, sizeof(index_buffer), "%d", index); + snprintf(buffer, sizeof(buffer), "%s,%d", LocalFlags[index].VariableName, LocalFlags[index].Value ? 1 : 0); ini.Put_String(SECTION, index_buffer, buffer); } } @@ -4182,7 +4182,7 @@ void ScenarioClass::Read_Waypoints(CCINIClass const & ini) char buf[20]; for (int i = 0; i < WAYPT_COUNT; i++) { - wsprintf(buf, "%d", i); + snprintf(buf, sizeof(buf), "%d", i); int val = ini.Get_Int("Waypoints", buf, 0); if (val == 0) { Waypoint[i] = CELL_NONE; @@ -4219,7 +4219,7 @@ void ScenarioClass::Write_Waypoints(CCINIClass & ini) const ini.Clear(WAYNAME); for (int i = 0; i < WAYPT_COUNT; i++) { if (Waypoint[i] != CELL_NONE) { - wsprintf(entry, "%d", i); + snprintf(entry, sizeof(entry), "%d", i); ini.Put_Int(WAYNAME, entry, Waypoint[i].Y * 1000 + Waypoint[i].X); } } diff --git a/code/startup.cpp b/code/startup.cpp index ee17b98dc..3b9a75f09 100644 --- a/code/startup.cpp +++ b/code/startup.cpp @@ -532,7 +532,7 @@ int CALLBACK WinMain ( HINSTANCE instance , HINSTANCE , char * , int command_sho ** If there is not enough disk space free, don't allow the product to run. */ if (Disk_Space_Available() < INIT_FREE_DISK_SPACE) { - wsprintf (buffer, Fetch_String(TXT_CRITICALLY_LOW), (INIT_FREE_DISK_SPACE) / (1024 * 1024)); + snprintf(buffer, sizeof(buffer), Fetch_String(TXT_CRITICALLY_LOW), (INIT_FREE_DISK_SPACE) / (1024 * 1024)); int reply = MessageBox(NULL, buffer, Fetch_String(TXT_SHORT_TITLE), MB_ICONQUESTION|MB_YESNO); if (reply == IDNO) { return(EXIT_FAILURE); diff --git a/code/stats.cpp b/code/stats.cpp index 45628b66e..789a3c415 100644 --- a/code/stats.cpp +++ b/code/stats.cpp @@ -416,7 +416,7 @@ void Send_Statistics_Packet(void) * Game version/build date */ char version[128]; - wsprintf (version, "V%s", VerNum.Version_Name() ); + snprintf(version, sizeof(version), "V%s", VerNum.Version_Name() ); stats.Add_Field (FIELD_GAME_VERSION, (char*)version); char path_to_exe[280]; diff --git a/code/tagtype.cpp b/code/tagtype.cpp index 26bef7fbf..135dfb6a8 100644 --- a/code/tagtype.cpp +++ b/code/tagtype.cpp @@ -240,10 +240,10 @@ bool TagTypeClass::Write_INI(CCINIClass & ini) const char buffer[128]; if (FirstTrigger == NULL) { - wsprintf(buffer, "%s,", (char const *)GivenName); + snprintf(buffer, sizeof(buffer), "%s,", (char const *)GivenName); ini.Put_String(INI_NAME, IniName, buffer); } else { - wsprintf(buffer, "%d,%s,%s", Persistence, (char const *)GivenName, (char const *)FirstTrigger->IniName); + snprintf(buffer, sizeof(buffer), "%d,%s,%s", Persistence, (char const *)GivenName, (char const *)FirstTrigger->IniName); ini.Put_String(INI_NAME, IniName, buffer); } diff --git a/code/tevent.cpp b/code/tevent.cpp index 2b724d56a..a556428c5 100644 --- a/code/tevent.cpp +++ b/code/tevent.cpp @@ -490,18 +490,23 @@ bool TEventClass::operator () (TEventType event, HouseClass const * house, Objec * HISTORY: * * 11/28/1995 JLB : Created. * *=============================================================================================*/ -void TEventClass::Build_INI_Entry(char * ptr) const +void TEventClass::Build_INI_Entry(char * ptr, std::size_t size) const { int code = 0; int val = Data.Value; NeedType need = Event_Needs(Event); + + // The caller has already put the event count and a comma in the buffer, so this appends. + std::size_t const used = strlen(ptr); + if (used >= size) { + return; + } + if (Team != NULL) { code = 1; - ptr += strlen(ptr); - wsprintf(ptr, "%d,%d,%s", Event, code, (char const *)Team->IniName); + snprintf(ptr + used, size - used, "%d,%d,%s", Event, code, (char const *)Team->IniName); } else { - ptr += strlen(ptr); - wsprintf(ptr, "%d,%d,%d", Event, code, val); + snprintf(ptr + used, size - used, "%d,%d,%d", Event, code, val); } } diff --git a/code/tevent.h b/code/tevent.h index c7dc9e1bf..2bd48a350 100644 --- a/code/tevent.h +++ b/code/tevent.h @@ -46,6 +46,8 @@ #include "tevent.hh" #include "unit.hh" +#include + template class DynamicVectorClass; class TeamTypeClass; class TechnoClass; @@ -109,7 +111,7 @@ class TEventClass : public AbstractClass virtual void Serialize(SaveStreamClass & stream) override; void Read_INI(void); - void Build_INI_Entry(char * buffer) const; + void Build_INI_Entry(char * buffer, std::size_t size) const; virtual void Compute_CRC(CRCEngine & crc) const override; virtual void Detach(AbstractClass const * target, bool all=true) override; diff --git a/code/trigtype.cpp b/code/trigtype.cpp index 849f89755..081d45048 100644 --- a/code/trigtype.cpp +++ b/code/trigtype.cpp @@ -649,7 +649,7 @@ bool TriggerTypeClass::Write_INI(CCINIClass & ini) const tevent = FirstEvent; while (tevent != NULL) { strcat(buffer, ","); - tevent->Build_INI_Entry(buffer); + tevent->Build_INI_Entry(buffer, sizeof(buffer)); tevent = tevent->Next; } ini.Put_String(INI_EVENT_NAME, IniName, buffer); diff --git a/code/waypoint.cpp b/code/waypoint.cpp index 59d2f4fb3..eac7f049e 100644 --- a/code/waypoint.cpp +++ b/code/waypoint.cpp @@ -44,11 +44,11 @@ const char *Waypoint_To_Name(WAYPOINT wp) if (wp < num_chars) { - wsprintf(_string, "%c", wp + 'A'); + snprintf(_string, sizeof(_string), "%c", wp + 'A'); return(_string); } - wsprintf(_string, "%c%c", (wp / num_chars) + ('A' - 1), (wp % num_chars) + 'A'); + snprintf(_string, sizeof(_string), "%c%c", (wp / num_chars) + ('A' - 1), (wp % num_chars) + 'A'); return(_string); } diff --git a/code/winfix.cpp b/code/winfix.cpp index c23c43d49..18561bfb4 100644 --- a/code/winfix.cpp +++ b/code/winfix.cpp @@ -440,7 +440,7 @@ BOOL CALLBACK read_view_from_ini(HWND window, INIClass const &ini) HTREEITEM item = TreeView_GetRoot(window); while (item != NULL) { i++; - wsprintf(buffer, "TV%d", i); + snprintf(buffer, sizeof(buffer), "TV%d", i); if (ini.Get_Bool(section, buffer, false)) { TreeView_Expand(window, item, TVE_EXPAND); @@ -460,7 +460,7 @@ BOOL CALLBACK read_view_from_ini(HWND window, INIClass const &ini) section = last_view_ini_section_name; if (window != NULL) { for (int i = 0; i < 10; i++) { - wsprintf(buffer, "LV%d", i); + snprintf(buffer, sizeof(buffer), "LV%d", i); unsigned int width = ListView_GetColumnWidth(window, i); width = ini.Get_Int(section, buffer, width); if (width < 1000) { @@ -543,7 +543,7 @@ BOOL CALLBACK write_view_to_ini(HWND window, INIClass &ini) while (item != NULL) { i++; - wsprintf(buf, "TV%d", i); + snprintf(buf, sizeof(buf), "TV%d", i); TVITEM *tmp = (TVITEM *)buffer; tmp->mask = TVIF_HANDLE|TVIF_STATE; @@ -570,7 +570,7 @@ BOOL CALLBACK write_view_to_ini(HWND window, INIClass &ini) section = last_view_ini_section_name; if (window != NULL) { for (int i = 0; i < 10; i++) { - wsprintf(buf, "LV%d", i); + snprintf(buf, sizeof(buf), "LV%d", i); unsigned int width = ListView_GetColumnWidth(window, i); if (width < 1000) { ini.Put_Int(section, buf, width); @@ -619,11 +619,11 @@ const char *Make_Identifier(char *str, int num) if ( str ) { - wsprintf(_buffer, "%s%d", str, num); + snprintf(_buffer, sizeof(_buffer), "%s%d", str, num); } else { - wsprintf(_buffer, "%d", num); + snprintf(_buffer, sizeof(_buffer), "%d", num); } return(_buffer); }