G_SaveDemo: Resolve memory errors that could result in crashes

- Empty `demo.titlename` case
    - Don't try to save demo of name `.lmp`
    - Doesn't fall back to anything, because emptying out the name field can be reasonably treated as not wanting to save
- `demo.titlename` consists only of invalid characters
    - Don't try to save demo of name `-.lmp`
    - Falls back to the default demo title, because the user clearly wanted to save and just happened to provide invalid text
This commit is contained in:
toaster 2024-05-01 19:54:09 +01:00
parent dcd0fe7feb
commit 7390ee5442
2 changed files with 26 additions and 7 deletions

View file

@ -4135,7 +4135,7 @@ void G_SaveDemo(void)
strindex++;
dash = false;
}
else if (!dash)
else if (strindex && !dash)
{
demo_slug[strindex] = '-';
strindex++;
@ -4143,12 +4143,31 @@ void G_SaveDemo(void)
}
}
demo_slug[strindex] = 0;
if (dash) demo_slug[strindex-1] = 0;
if (dash && strindex)
{
strindex--;
}
demo_slug[strindex] = '\0';
writepoint = strstr(strrchr(demoname, *PATHSEP), "-") + 1;
demo_slug[128 - (writepoint - demoname) - 4] = 0;
sprintf(writepoint, "%s.lmp", demo_slug);
if (demo_slug[0] != '\0')
{
// Slug is valid, write the chosen filename.
writepoint = strstr(strrchr(demoname, *PATHSEP), "-") + 1;
demo_slug[128 - (writepoint - demoname) - 4] = 0;
sprintf(writepoint, "%s.lmp", demo_slug);
}
else if (demo.titlename[0] == '\0')
{
// Slug is completely blank? Will crash if we attempt to save
// No bailout because empty seems like a good "no thanks" choice
G_ResetDemoRecording();
return;
}
// If a title that is invalid is provided, the user clearly wanted
// to save. But we can't do so at that name, so we only apply the
// title INSIDE the file, not in the naked filesystem.
// (A hypothetical example is bamboozling bot behaviour causing
// a player to write "?????????".) ~toast 010524
}
length = *(UINT32 *)demoinfo_p;

View file

@ -1490,7 +1490,7 @@ void ST_DrawSaveReplayHint(INT32 flags)
V_DrawRightAlignedThinString(
BASEVIDWIDTH - 2, 2,
flags|V_YELLOWMAP,
demo.willsave ? "Replay will be saved. \xAB Change title" : "\xAB or \xAD Save replay"
(demo.willsave && demo.titlename[0]) ? "Replay will be saved. \xAB Change title" : "\xAB or \xAD Save replay"
);
}