Fix crash when page text is empty; add checks for MAX_PROMPTS and MAX_PAGES

This commit is contained in:
mazmazz 2018-11-09 21:55:14 -05:00
parent 311cb27818
commit b8897db308
3 changed files with 18 additions and 12 deletions

View File

@ -1773,17 +1773,17 @@ static void readtextprompt(MYFILE *f, INT32 num)
if (fastcmp(word, "NUMPAGES"))
{
textprompts[num]->numpages = value;
textprompts[num]->numpages = min(max(value, 0), MAX_PAGES);
}
else if (fastcmp(word, "PAGE"))
{
if (1 <= value && value <= 128)
if (1 <= value && value <= MAX_PAGES)
{
textprompts[num]->page[value - 1].backcolor = UINT8_MAX; // non-zero default
readtextpromptpage(f, num, value - 1);
}
else
deh_warning("Page number %d out of range (1 - 128)", value);
deh_warning("Page number %d out of range (1 - %d)", value, MAX_PAGES);
}
else

View File

@ -166,6 +166,9 @@ typedef struct
extern cutscene_t *cutscenes[128];
#define MAX_PROMPTS 256
#define MAX_PAGES 128
typedef struct
{
char name[32]; // narrator name
@ -186,11 +189,11 @@ typedef struct
typedef struct
{
textpage_t page[128]; // 128 pages per prompt.
textpage_t page[MAX_PAGES];
INT32 numpages; // Number of pages in this prompt
} textprompt_t;
extern textprompt_t *textprompts[256];
extern textprompt_t *textprompts[MAX_PROMPTS];
// For the Custom Exit linedef.
extern INT16 nextmapoverride;

View File

@ -2065,7 +2065,7 @@ static void F_PreparePageText(char *pagetext)
if (promptpagetext)
Z_Free(promptpagetext);
promptpagetext = V_WordWrap(textx, textr, 0, pagetext);
promptpagetext = (pagetext && pagetext[0]) ? V_WordWrap(textx, textr, 0, pagetext) : "";
F_NewCutscene(promptpagetext);
cutscene_textspeed = textprompts[cutnum]->page[scenenum].textspeed ? textprompts[cutnum]->page[scenenum].textspeed : TICRATE/5;
@ -2085,7 +2085,7 @@ static void F_AdvanceToNextPage(void)
// determine next prompt
if (nextprompt)
{
if (textprompts[nextprompt-1])
if (nextprompt <= MAX_PROMPTS && textprompts[nextprompt-1])
cutnum = nextprompt-1;
else
cutnum = INT32_MAX;
@ -2095,14 +2095,14 @@ static void F_AdvanceToNextPage(void)
if (nextpage)
{
scenenum = nextpage-1;
if (scenenum > textprompts[cutnum]->numpages-1)
if (scenenum >= MAX_PAGES || scenenum > textprompts[cutnum]->numpages-1)
scenenum = INT32_MAX;
}
else
{
if (cutnum != oldcutnum)
scenenum = 0;
else if (scenenum < textprompts[cutnum]->numpages-1)
else if (scenenum + 1 < MAX_PAGES && scenenum < textprompts[cutnum]->numpages-1)
scenenum++;
else
scenenum = INT32_MAX;
@ -2157,8 +2157,8 @@ void F_StartTextPrompt(INT32 promptnum, INT32 pagenum, mobj_t *mo, UINT16 postex
(void)freezerealtime; // \todo freeze player->realtime, maybe this needs to cycle through player thinkers
// Initialize current prompt and scene
cutnum = (textprompts[promptnum]) ? promptnum : INT32_MAX;
scenenum = (cutnum != INT32_MAX && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX;
cutnum = (promptnum < MAX_PROMPTS && textprompts[promptnum]) ? promptnum : INT32_MAX;
scenenum = (cutnum != INT32_MAX && pagenum < MAX_PAGES && pagenum <= textprompts[cutnum]->numpages-1) ? pagenum : INT32_MAX;
promptactive = (cutnum != INT32_MAX && scenenum != INT32_MAX);
if (promptactive)
@ -2320,7 +2320,10 @@ void F_TextPromptTicker(void)
}
// generate letter-by-letter text
if (!F_WriteText())
if (scenenum >= MAX_PAGES ||
!textprompts[cutnum]->page[scenenum].text ||
!textprompts[cutnum]->page[scenenum].text[0] ||
!F_WriteText())
timetonext = !promptblockcontrols; // never show the chevron if we can't toggle pages
}