[model] Clean up the model array a little

Probably not really necessary, but I think I found a small opportunity
for a buffer overflow in there while I was modifying the code, so this
is probably better anyway.
This commit is contained in:
Bill Currie 2021-02-01 15:02:42 +09:00
parent bb6c6963d2
commit f02b35a20c
1 changed files with 15 additions and 16 deletions

View File

@ -39,6 +39,7 @@
#endif #endif
#include "QF/cvar.h" #include "QF/cvar.h"
#include "QF/darray.h"
#include "QF/iqm.h" #include "QF/iqm.h"
#include "QF/model.h" #include "QF/model.h"
#include "QF/qendian.h" #include "QF/qendian.h"
@ -53,9 +54,8 @@
vid_model_funcs_t *mod_funcs; vid_model_funcs_t *mod_funcs;
#define MOD_BLOCK 16 // allocate 16 models at a time #define MOD_BLOCK 16 // allocate 16 models at a time
model_t **mod_known; static struct DARRAY_TYPE (model_t *) mod_known = {0, 0, MOD_BLOCK};
int mod_numknown; static size_t mod_numknown;
int mod_maxknown;
VISIBLE texture_t *r_notexture_mip; VISIBLE texture_t *r_notexture_mip;
@ -115,10 +115,10 @@ Mod_Init_Cvars (void)
VISIBLE void VISIBLE void
Mod_ClearAll (void) Mod_ClearAll (void)
{ {
int i; size_t i;
model_t **mod; model_t **mod;
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) { for (i = 0, mod = mod_known.a; i < mod_numknown; i++, mod++) {
//FIXME this seems to be correct but need to double check the behavior //FIXME this seems to be correct but need to double check the behavior
//with alias models //with alias models
if (!(*mod)->needload && (*mod)->clear) { if (!(*mod)->needload && (*mod)->clear) {
@ -134,25 +134,24 @@ Mod_ClearAll (void)
model_t * model_t *
Mod_FindName (const char *name) Mod_FindName (const char *name)
{ {
int i; size_t i;
model_t **mod; model_t **mod;
if (!name[0]) if (!name[0])
Sys_Error ("Mod_FindName: empty name"); Sys_Error ("Mod_FindName: empty name");
// search the currently loaded models // search the currently loaded models
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) for (i = 0, mod = mod_known.a; i < mod_numknown; i++, mod++)
if (!strcmp ((*mod)->path, name)) if (!strcmp ((*mod)->path, name))
break; break;
if (i == mod_numknown) { if (i == mod_numknown) {
if (mod_numknown == mod_maxknown) { if (mod_numknown == mod_known.size) {
mod_maxknown += MOD_BLOCK; model_t *block = calloc (MOD_BLOCK, sizeof (model_t));
mod_known = realloc (mod_known, mod_maxknown * sizeof (model_t *)); for (i = 0; i < MOD_BLOCK; i++) {
mod = mod_known + mod_numknown; DARRAY_APPEND (&mod_known, &block[i]);
*mod = calloc (MOD_BLOCK, sizeof (model_t)); }
for (i = 1; i < MOD_BLOCK; i++) mod = &mod_known.a[mod_numknown];
mod[i] = mod[0] + i;
} }
memset ((*mod), 0, sizeof (model_t)); memset ((*mod), 0, sizeof (model_t));
strncpy ((*mod)->path, name, sizeof (*mod)->path - 1); strncpy ((*mod)->path, name, sizeof (*mod)->path - 1);
@ -301,11 +300,11 @@ Mod_TouchModel (const char *name)
VISIBLE void VISIBLE void
Mod_Print (void) Mod_Print (void)
{ {
int i; size_t i;
model_t **mod; model_t **mod;
Sys_Printf ("Cached models:\n"); Sys_Printf ("Cached models:\n");
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) { for (i = 0, mod = mod_known.a; i < mod_numknown; i++, mod++) {
Sys_Printf ("%8p : %s\n", (*mod)->cache.data, (*mod)->path); Sys_Printf ("%8p : %s\n", (*mod)->cache.data, (*mod)->path);
} }
} }