diff --git a/src/deh_soc.c b/src/deh_soc.c index df11a3e6d..343beb301 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -286,6 +286,7 @@ void readPlayer(MYFILE *f, INT32 num) } if (playertext) { + // PLAYERTEXT is really weird, so this doesn't use deh_strlcpy. strlcpy(description[num].notes, playertext, NOTE_SIZE); strlcat(description[num].notes, myhashfgets(playertext, NOTE_SIZE, f), NOTE_SIZE); @@ -324,7 +325,8 @@ void readPlayer(MYFILE *f, INT32 num) if (fastcmp(word, "PICNAME")) { SLOTFOUND - strncpy(description[num].picname, word2, sizeof(description[num].picname)-1); + deh_strlcpy(description[num].picname, word2, sizeof description[num].picname, + va("Character %d: picname", num)); } else if (fastcmp(word, "DISPLAYNAME")) { @@ -345,7 +347,8 @@ void readPlayer(MYFILE *f, INT32 num) cur = strchr(cur, '#'); } - strlcpy(description[num].displayname, stringvalue, sizeof description[num].displayname); + deh_strlcpy(description[num].displayname, stringvalue, sizeof description[num].displayname, + va("Character %d: displayname", num)); } else if (fastcmp(word, "OPPOSITECOLOR") || fastcmp(word, "OPPOSITECOLOUR")) { @@ -355,7 +358,8 @@ void readPlayer(MYFILE *f, INT32 num) else if (fastcmp(word, "NAMETAG") || fastcmp(word, "TAGNAME")) { SLOTFOUND - strncpy(description[num].nametag, word2, sizeof(description[num].nametag)-1); + deh_strlcpy(description[num].nametag, word2, sizeof description[num].nametag, + va("Character %d: nametag", num)); } else if (fastcmp(word, "TAGTEXTCOLOR") || fastcmp(word, "TAGTEXTCOLOUR")) { @@ -387,7 +391,8 @@ void readPlayer(MYFILE *f, INT32 num) { // Send to free slot. SLOTFOUND - strlcpy(description[num].skinname, word2, sizeof description[num].skinname); + deh_strlcpy(description[num].skinname, word2, sizeof description[num].skinname, + va("Character %d: skinname", num)); strlwr(description[num].skinname); } else if (!failure) @@ -1196,6 +1201,7 @@ void readgametype(MYFILE *f, char *gtname) } if (descr) { + // DESCRIPTION is really weird, so this doesn't use deh_strlcpy. strlcpy(gtdescription, descr, sizeof (gtdescription)); strlcat(gtdescription, myhashfgets(descr, sizeof (gtdescription), f), @@ -1402,7 +1408,7 @@ void readlevelheader(MYFILE *f, INT32 num) { deh_strlcpy(mapheaderinfo[num-1]->lvlttl, word2, sizeof(mapheaderinfo[num-1]->lvlttl), va("Level header %d: levelname", num)); - strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_ so only complains once + strlcpy(mapheaderinfo[num-1]->selectheading, word2, sizeof(mapheaderinfo[num-1]->selectheading)); // not deh_strlcpy so only complains once continue; } // CHEAP HACK: move this over here for lowercase subtitles @@ -1445,10 +1451,10 @@ void readlevelheader(MYFILE *f, INT32 num) // Newly allocated modoption = &mapheaderinfo[num-1]->customopts[j]; - strncpy(modoption->option, word, 31); - modoption->option[31] = '\0'; - strncpy(modoption->value, word2, 255); - modoption->value[255] = '\0'; + deh_strlcpy(modoption->option, word, sizeof(modoption->option), + va("Level header %d: custom option %d key", num, j)); + deh_strlcpy(modoption->value, word2, sizeof(modoption->value), + va("Level header %d: custom option %d value", num, j)); continue; } @@ -1626,7 +1632,7 @@ void readlevelheader(MYFILE *f, INT32 num) else if (fastcmp(word, "KEYWORDS")) { deh_strlcpy(mapheaderinfo[num-1]->keywords, word2, - sizeof(mapheaderinfo[num-1]->keywords), va("Level header %d: keywords", num)); + sizeof(mapheaderinfo[num-1]->keywords), va("Level header %d: keywords", num)); } else if (fastcmp(word, "MUSIC")) { @@ -1675,7 +1681,8 @@ void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "FORCECHARACTER")) { - strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1); + deh_strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, sizeof mapheaderinfo[num-1]->forcecharacter, + va("Level header %d: forcecharacter", num)); strlwr(mapheaderinfo[num-1]->forcecharacter); // skin names are lowercase } else if (fastcmp(word, "WEATHER")) @@ -1683,7 +1690,10 @@ void readlevelheader(MYFILE *f, INT32 num) else if (fastcmp(word, "SKYNUM")) mapheaderinfo[num-1]->skynum = (INT16)i; else if (fastcmp(word, "INTERSCREEN")) - strncpy(mapheaderinfo[num-1]->interscreen, word2, sizeof(mapheaderinfo[num-1]->interscreen)-1); + { + deh_strlcpy(mapheaderinfo[num-1]->interscreen, word2, sizeof mapheaderinfo[num-1]->interscreen, + va("Level header %d: interscreen", num)); + } else if (fastcmp(word, "PRECUTSCENENUM")) mapheaderinfo[num-1]->precutscenenum = (UINT8)i; else if (fastcmp(word, "CUTSCENENUM")) @@ -1985,14 +1995,17 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) picid = (UINT8)atoi(word + 3); if (picid > 8 || picid == 0) { - deh_warning("CutSceneScene %d: unknown word '%s'", num, word); + deh_warning("Cutscene %d, scene %d: pic number %d out of range (1 - %d)", + num + 1, scenenum + 1, picid, 8); continue; } --picid; if (fastcmp(word+4, "NAME")) { - strncpy(cutscenes[num]->scene[scenenum].picname[picid], word2, 8); + deh_strlcpy(cutscenes[num]->scene[scenenum].picname[picid], word2, + sizeof cutscenes[num]->scene[scenenum].picname[picid], + va("Cutscene %d, scene %d, pic %d: name", num + 1, scenenum + 1, picid + 1)); } else if (fastcmp(word+4, "HIRES")) { @@ -2011,12 +2024,13 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) cutscenes[num]->scene[scenenum].ycoord[picid] = usi; } else - deh_warning("CutSceneScene %d: unknown word '%s'", num, word); + deh_warning("Cutscene %d, scene %d: unknown word '%s'", num + 1, scenenum + 1, word); } else if (fastcmp(word, "MUSIC")) { - strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7); - cutscenes[num]->scene[scenenum].musswitch[6] = 0; + deh_strlcpy(cutscenes[num]->scene[scenenum].musswitch, word2, + sizeof cutscenes[num]->scene[scenenum].musswitch, + va("Cutscene %d, scene %d: music", num + 1, scenenum + 1)); } else if (fastcmp(word, "MUSICTRACK")) { @@ -2051,7 +2065,7 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) cutscenes[num]->scene[scenenum].fadecolor = (UINT8)i; } else - deh_warning("CutSceneScene %d: unknown word '%s'", num, word); + deh_warning("Cutscene %d, scene %d: unknown word '%s'", num + 1, scenenum + 1, word); } } while (!myfeof(f)); // finish when the line is empty @@ -2109,11 +2123,10 @@ void readcutscene(MYFILE *f, INT32 num) readcutscenescene(f, num, value - 1); } else - deh_warning("Scene number %d out of range (1 - 128)", value); - + deh_warning("Cutscene %d: scene number %d out of range (1 - 128)", num + 1, value); } else - deh_warning("Cutscene %d: unknown word '%s', Scene expected.", num, word); + deh_warning("Cutscene %d: unknown word '%s', Scene expected.", num + 1, word); } } while (!myfeof(f)); // finish when the line is empty @@ -2234,7 +2247,8 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) for (picid = 0; picid < MAX_PROMPT_PICS; picid++) { - strncpy(textprompts[num]->page[pagenum].picname[picid], textprompts[num]->page[metapagenum].picname[picid], 8); + // Doesn't use deh_strlcpy because it's not copying input. + strlcpy(textprompts[num]->page[pagenum].picname[picid], textprompts[num]->page[metapagenum].picname[picid], sizeof textprompts[num]->page[pagenum].picname[picid]); textprompts[num]->page[pagenum].pichires[picid] = textprompts[num]->page[metapagenum].pichires[picid]; textprompts[num]->page[pagenum].picduration[picid] = textprompts[num]->page[metapagenum].picduration[picid]; textprompts[num]->page[pagenum].xcoord[picid] = textprompts[num]->page[metapagenum].xcoord[picid]; @@ -2247,14 +2261,17 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) picid = (UINT8)atoi(word + 3); if (picid > MAX_PROMPT_PICS || picid == 0) { - deh_warning("textpromptscene %d: unknown word '%s'", num, word); + deh_warning("Text prompt %d, page %d: pic number %d out of range (1 - %d)", + num + 1, pagenum + 1, picid, MAX_PROMPT_PICS); continue; } --picid; if (fastcmp(word+4, "NAME")) { - strncpy(textprompts[num]->page[pagenum].picname[picid], word2, 8); + deh_strlcpy(textprompts[num]->page[pagenum].picname[picid], word2, + sizeof textprompts[num]->page[pagenum].picname[picid], + va("Text prompt %d, page %d, pic %d: name", num + 1, pagenum + 1, picid + 1)); } else if (fastcmp(word+4, "HIRES")) { @@ -2273,12 +2290,16 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) textprompts[num]->page[pagenum].ycoord[picid] = usi; } else - deh_warning("textpromptscene %d: unknown word '%s'", num, word); + { + deh_warning("Text prompt %d, page %d: unknown word '%s'", + num + 1, pagenum + 1, word); + } } else if (fastcmp(word, "MUSIC")) { - strncpy(textprompts[num]->page[pagenum].musswitch, word2, 7); - textprompts[num]->page[pagenum].musswitch[6] = 0; + deh_strlcpy(textprompts[num]->page[pagenum].musswitch, word2, + sizeof textprompts[num]->page[pagenum].musswitch, + va("Text prompt %d, page %d: music", num + 1, pagenum + 1)); } else if (fastcmp(word, "MUSICTRACK")) { @@ -2293,30 +2314,35 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) { if (*word2 != '\0') { - INT32 j; + size_t j; // HACK: Add yellow control char now // so the drawing function doesn't call it repeatedly - char name[34]; + char name[32 + 2]; name[0] = '\x82'; // color yellow - name[1] = 0; - strncat(name, word2, 32); - name[33] = 0; + + // So that we still get a warning. + deh_strlcpy(name + 1, word2, (sizeof(name)) - 1, + va("Text prompt %d, page %d: name", num + 1, pagenum + 1)); // Replace _ with ' ' - for (j = 0; j < 32 && name[j]; j++) + for (j = 1; j < sizeof(name) && name[j]; j++) { if (name[j] == '_') name[j] = ' '; } - strncpy(textprompts[num]->page[pagenum].name, name, sizeof(textprompts[num]->page[pagenum].name)); + strlcpy(textprompts[num]->page[pagenum].name, name, sizeof(textprompts[num]->page[pagenum].name)); } else *textprompts[num]->page[pagenum].name = '\0'; } else if (fastcmp(word, "ICON")) - strncpy(textprompts[num]->page[pagenum].iconname, word2, 8); + { + deh_strlcpy(textprompts[num]->page[pagenum].iconname, word2, + sizeof textprompts[num]->page[pagenum].iconname, + va("Text prompt %d, page %d: icon", num + 1, pagenum + 1)); + } else if (fastcmp(word, "ICONALIGN")) textprompts[num]->page[pagenum].rightside = (i || word2[0] == 'R'); else if (fastcmp(word, "ICONFLIP")) @@ -2383,8 +2409,9 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) { UINT8 metapagenum = usi - 1; - strncpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, 32); - strncpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, 8); + // Doesn't use deh_strlcpy because it's not copying input. + strlcpy(textprompts[num]->page[pagenum].name, textprompts[num]->page[metapagenum].name, sizeof textprompts[num]->page[pagenum].name); + strlcpy(textprompts[num]->page[pagenum].iconname, textprompts[num]->page[metapagenum].iconname, sizeof textprompts[num]->page[pagenum].iconname); textprompts[num]->page[pagenum].rightside = textprompts[num]->page[metapagenum].rightside; textprompts[num]->page[pagenum].iconflip = textprompts[num]->page[metapagenum].iconflip; textprompts[num]->page[pagenum].lines = textprompts[num]->page[metapagenum].lines; @@ -2399,17 +2426,25 @@ static void readtextpromptpage(MYFILE *f, INT32 num, INT32 pagenum) } } else if (fastcmp(word, "TAG")) - strncpy(textprompts[num]->page[pagenum].tag, word2, 33); + { + deh_strlcpy(textprompts[num]->page[pagenum].tag, word2, + sizeof textprompts[num]->page[pagenum].tag, + va("Text prompt %d, page %d: tag", num + 1, pagenum + 1)); + } else if (fastcmp(word, "NEXTPROMPT")) textprompts[num]->page[pagenum].nextprompt = usi; else if (fastcmp(word, "NEXTPAGE")) textprompts[num]->page[pagenum].nextpage = usi; else if (fastcmp(word, "NEXTTAG")) - strncpy(textprompts[num]->page[pagenum].nexttag, word2, 33); + { + deh_strlcpy(textprompts[num]->page[pagenum].nexttag, word2, + sizeof textprompts[num]->page[pagenum].nexttag, + va("Text prompt %d, page %d: nexttag", num + 1, pagenum + 1)); + } else if (fastcmp(word, "TIMETONEXT")) textprompts[num]->page[pagenum].timetonext = get_number(word2); else - deh_warning("PromptPage %d: unknown word '%s'", num, word); + deh_warning("Text prompt %d, page %d: unknown word '%s'", num + 1, pagenum + 1, word); } } while (!myfeof(f)); // finish when the line is empty @@ -2469,11 +2504,11 @@ void readtextprompt(MYFILE *f, INT32 num) readtextpromptpage(f, num, value - 1); } else - deh_warning("Page number %d out of range (1 - %d)", value, MAX_PAGES); + deh_warning("Prompt %d: page number %d out of range (1 - %d)", num + 1, value, MAX_PAGES); } else - deh_warning("Prompt %d: unknown word '%s', Page expected.", num, word); + deh_warning("Prompt %d: unknown word '%s', Page expected.", num + 1, word); } } while (!myfeof(f)); // finish when the line is empty @@ -2522,7 +2557,8 @@ void readmenu(MYFILE *f, INT32 num) if (fastcmp(word, "BACKGROUNDNAME")) { - strncpy(menupres[num].bgname, word2, 8); + deh_strlcpy(menupres[num].bgname, word2, + sizeof menupres[num].bgname, va("Menu %d: backgroundname", num)); titlechanged = true; } else if (fastcmp(word, "HIDEBACKGROUND")) @@ -2565,7 +2601,8 @@ void readmenu(MYFILE *f, INT32 num) } else if (fastcmp(word, "TITLEPICSNAME")) { - strncpy(menupres[num].ttname, word2, 9); + deh_strlcpy(menupres[num].ttname, word2, + sizeof menupres[num].ttname, va("Menu %d: titlepicsname", num)); titlechanged = true; } else if (fastcmp(word, "TITLEPICSX")) @@ -2601,8 +2638,8 @@ void readmenu(MYFILE *f, INT32 num) } else if (fastcmp(word, "MUSIC")) { - strncpy(menupres[num].musname, word2, 7); - menupres[num].musname[6] = 0; + deh_strlcpy(menupres[num].musname, word2, + sizeof menupres[num].musname, va("Menu %d: music", num)); titlechanged = true; } else if (fastcmp(word, "MUSICTRACK")) @@ -3590,9 +3627,7 @@ void readmaincfg(MYFILE *f) lumpnum_t lumpnum; char newname[9]; - strncpy(newname, word2, 8); - - newname[8] = '\0'; + deh_strlcpy(newname, word2, sizeof newname, va("Maincfg: execcfg")); lumpnum = W_CheckNumForName(newname); @@ -3800,7 +3835,7 @@ void readmaincfg(MYFILE *f) } else if (fastcmp(word, "TITLEPICSNAME")) { - strncpy(ttname, word2, sizeof(ttname)-1); + deh_strlcpy(ttname, word2, sizeof ttname, va("Maincfg: titlepicsname")); titlechanged = true; } else if (fastcmp(word, "TITLEPICSX")) @@ -3910,7 +3945,7 @@ void readmaincfg(MYFILE *f) } else if (fastcmp(word, "CUSTOMVERSION")) { - strlcpy(customversionstring, word2, sizeof (customversionstring)); + deh_strlcpy(customversionstring, word2, sizeof customversionstring, va("Maincfg: customversion")); //titlechanged = true; } else if (fastcmp(word, "BOOTMAP")) diff --git a/src/doomstat.h b/src/doomstat.h index 5246349de..4abc9d21a 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -209,7 +209,7 @@ typedef struct UINT8 picmode; // sequence mode after displaying last pic, 0 = persist, 1 = loop, 2 = destroy UINT8 pictoloop; // if picmode == loop, which pic to loop to? UINT8 pictostart; // initial pic number to show - char picname[MAX_PROMPT_PICS][8]; + char picname[MAX_PROMPT_PICS][9]; UINT8 pichires[MAX_PROMPT_PICS]; UINT16 xcoord[MAX_PROMPT_PICS]; // gfx UINT16 ycoord[MAX_PROMPT_PICS]; // gfx @@ -221,7 +221,7 @@ typedef struct char tag[33]; // page tag char name[34]; // narrator name, extra char for color - char iconname[8]; // narrator icon lump + char iconname[9]; // narrator icon lump boolean rightside; // narrator side, false = left, true = right boolean iconflip; // narrator flip icon horizontally UINT8 hidehud; // hide hud, 0 = show all, 1 = hide depending on prompt position (top/bottom), 2 = hide all diff --git a/src/m_menu.h b/src/m_menu.h index cfe811d0b..58c557341 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -3,7 +3,7 @@ // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -143,7 +143,7 @@ typedef enum typedef struct { - char bgname[8]; // name for background gfx lump; lays over titlemap if this is set + char bgname[9]; // name for background gfx lump; lays over titlemap if this is set SINT8 fadestrength; // darken background when displaying this menu, strength 0-31 or -1 for undefined INT32 bgcolor; // fill color, overrides bg name. -1 means follow bg name rules. INT32 titlescrollxspeed; // background gfx scroll per menu; inherits global setting @@ -371,7 +371,7 @@ typedef struct { boolean used; char notes[441]; - char picname[8]; + char picname[9]; char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 patch_t *charpic; UINT8 prev; @@ -379,7 +379,7 @@ typedef struct char displayname[SKINNAMESIZE+1]; INT16 skinnum[2]; UINT16 oppositecolor; - char nametag[8+1]; + char nametag[9]; patch_t *namepic; UINT16 tagtextcolor; UINT16 tagoutlinecolor;