[model] Mark all cleared models as cleared

This fixes a nine year old bug that I discovered only today thanks to
the vulkan renderer. The problem was that when a model had a clear
callback, it was not getting marked as needing to be reloaded, and thus
the model would be "reused" after being trampled on by another model
loading over it.

Also, plug a potential string buffer overflow (strcpy just will not
die!).
This commit is contained in:
Bill Currie 2021-01-20 13:55:50 +09:00
parent d33f5b8d0d
commit 7d9ef9a47e

View file

@ -122,14 +122,15 @@ Mod_ClearAll (void)
model_t **mod; model_t **mod;
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) { for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) {
//FIXME this seems to be correct but need to double check the behavior
//with alias models
if (!(*mod)->needload && (*mod)->clear) { if (!(*mod)->needload && (*mod)->clear) {
(*mod)->clear (*mod, (*mod)->data); (*mod)->clear (*mod, (*mod)->data);
} else {
if ((*mod)->type != mod_alias)
(*mod)->needload = true;
if ((*mod)->type == mod_sprite)
(*mod)->cache.data = 0;
} }
if ((*mod)->type != mod_alias)
(*mod)->needload = true;
if ((*mod)->type == mod_sprite)
(*mod)->cache.data = 0;
} }
} }
@ -156,7 +157,8 @@ Mod_FindName (const char *name)
for (i = 1; i < MOD_BLOCK; i++) for (i = 1; i < MOD_BLOCK; i++)
mod[i] = mod[0] + i; mod[i] = mod[0] + i;
} }
strcpy ((*mod)->name, name); memset ((*mod), 0, sizeof (model_t));
strncpy ((*mod)->name, name, sizeof (*mod)->name - 1);
(*mod)->needload = true; (*mod)->needload = true;
mod_numknown++; mod_numknown++;
Cache_Add (&(*mod)->cache, *mod, Mod_CallbackLoad); Cache_Add (&(*mod)->cache, *mod, Mod_CallbackLoad);