diff options
author | Andrey Nazarov <skuller@skuller.net> | 2012-08-03 19:51:46 +0400 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2012-08-03 19:51:46 +0400 |
commit | 92101f85480cdf6cffabaf9f68048d37c8c97e55 (patch) | |
tree | b613d1ae3d46bb5181359f74e62f04edd068e9ed | |
parent | 1ace24c87aaf0b49e342a2c3e1f9aa15f21d48dc (diff) |
Don't crash when image/model/sound tables overflow.
Print an error message instead. Also double model table size.
-rw-r--r-- | inc/common/error.h | 7 | ||||
-rw-r--r-- | src/client/sound/main.c | 15 | ||||
-rw-r--r-- | src/common/error.c | 1 | ||||
-rw-r--r-- | src/refresh/images.c | 29 | ||||
-rw-r--r-- | src/refresh/models.c | 16 |
5 files changed, 45 insertions, 23 deletions
diff --git a/inc/common/error.h b/inc/common/error.h index 6b7754e..2a9702e 100644 --- a/inc/common/error.h +++ b/inc/common/error.h @@ -51,10 +51,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #define Q_ERR_RUNAWAY_LOOP _Q_ERR(15) // Runaway loop avoided #define Q_ERR_INFINITE_LOOP _Q_ERR(16) // Infinite loop avoided #define Q_ERR_LIBRARY_ERROR _Q_ERR(17) // Library error +#define Q_ERR_OUT_OF_SLOTS _Q_ERR(18) // Out of slots #if USE_ZLIB -#define Q_ERR_INFLATE_FAILED _Q_ERR(18) // Inflate failed -#define Q_ERR_DEFLATE_FAILED _Q_ERR(19) // Deflate failed -#define Q_ERR_NOT_COHERENT _Q_ERR(20) // Coherency check failed +#define Q_ERR_INFLATE_FAILED _Q_ERR(19) // Inflate failed +#define Q_ERR_DEFLATE_FAILED _Q_ERR(20) // Deflate failed +#define Q_ERR_NOT_COHERENT _Q_ERR(21) // Coherency check failed #endif // These values directly map to system errno. diff --git a/src/client/sound/main.c b/src/client/sound/main.c index b2433aa..ce52b03 100644 --- a/src/client/sound/main.c +++ b/src/client/sound/main.c @@ -325,7 +325,7 @@ static sfx_t *S_AllocSfx(void) if (i == num_sfx) { if (num_sfx == MAX_SFX) - Com_Error(ERR_DROP, "S_AllocSfx: out of sfx_t"); + return NULL; num_sfx++; } @@ -353,9 +353,10 @@ static sfx_t *S_FindName(const char *name, size_t namelen) // allocate new one sfx = S_AllocSfx(); - memcpy(sfx->name, name, namelen + 1); - sfx->registration_sequence = s_registration_sequence; - + if (sfx) { + memcpy(sfx->name, name, namelen + 1); + sfx->registration_sequence = s_registration_sequence; + } return sfx; } @@ -413,6 +414,10 @@ qhandle_t S_RegisterSound(const char *name) } sfx = S_FindName(buffer, len); + if (!sfx) { + Com_DPrintf("%s: out of slots\n", __func__); + return 0; + } if (!s_registering) { S_LoadSound(sfx); @@ -457,7 +462,7 @@ static sfx_t *S_RegisterSexedSound(int entnum, const char *base) sfx = S_FindName(buffer, len); // see if it exists - if (!sfx->truename && !S_LoadSound(sfx)) { + if (sfx && !sfx->truename && !S_LoadSound(sfx)) { // no, revert to the male sound in the pak0.pak len = Q_concat(buffer, MAX_QPATH, "sound/player/male/", base + 1, NULL); diff --git a/src/common/error.c b/src/common/error.c index 3802e1b..84a8c3a 100644 --- a/src/common/error.c +++ b/src/common/error.c @@ -38,6 +38,7 @@ static const char *const error_table[] = { "Runaway loop avoided", "Infinite loop avoided", "Library error", + "Out of slots", #if USE_ZLIB "Inflate failed", "Deflate failed", diff --git a/src/refresh/images.c b/src/refresh/images.c index 60ae852..94f591d 100644 --- a/src/refresh/images.c +++ b/src/refresh/images.c @@ -1461,7 +1461,7 @@ static image_t *alloc_image(void) if (i == r_numImages) { if (r_numImages == MAX_RIMAGES) - Com_Error(ERR_FATAL, "%s: MAX_IMAGES exceeded", __func__); + return NULL; r_numImages++; } @@ -1724,25 +1724,23 @@ static qerror_t find_or_load_image(const char *name, return ret; } -#if USE_REF == REF_GL - // don't need pics in memory after GL upload - if (!tmp) { - tmp = pic; - } -#endif - // allocate image slot image = alloc_image(); - memcpy(image->name, buffer, len + 1); - image->baselen = len - 4; - List_Append(&r_imageHash[hash], &image->entry); + if (!image) { + FS_FreeFile(tmp ? tmp : pic); + return Q_ERR_OUT_OF_SLOTS; + } // fill in some basic info - image->registration_sequence = registration_sequence; + memcpy(image->name, buffer, len + 1); + image->baselen = len - 4; image->type = type; image->flags = 0; image->width = width; image->height = height; + image->registration_sequence = registration_sequence; + + List_Append(&r_imageHash[hash], &image->entry); if (ret <= im_wal) { image->flags |= if_paletted; @@ -1760,6 +1758,13 @@ static qerror_t find_or_load_image(const char *name, // upload the image to card IMG_Load(image, pic, width, height); +#if USE_REF == REF_GL + // don't need pics in memory after GL upload + if (!tmp) { + tmp = pic; + } +#endif + // free any temp memory still remaining FS_FreeFile(tmp); diff --git a/src/refresh/models.c b/src/refresh/models.c index bc99216..2b7a408 100644 --- a/src/refresh/models.c +++ b/src/refresh/models.c @@ -30,7 +30,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "refresh/images.h" #include "refresh/models.h" -static model_t r_models[MAX_MODELS]; +// during registration it is possible to have more models than could actually +// be referenced during gameplay, because we don't want to free anything until +// we are sure we won't need it. +#define MAX_RMODELS (MAX_MODELS * 2) + +static model_t r_models[MAX_RMODELS]; static int r_numModels; static model_t *MOD_Alloc(void) @@ -45,8 +50,8 @@ static model_t *MOD_Alloc(void) } if (i == r_numModels) { - if (r_numModels == MAX_MODELS) { - Com_Error(ERR_DROP, "Model_Alloc: MAX_MODELS"); + if (r_numModels == MAX_RMODELS) { + return NULL; } r_numModels++; } @@ -353,6 +358,11 @@ qhandle_t R_RegisterModel(const char *name) } model = MOD_Alloc(); + if (!model) { + ret = Q_ERR_OUT_OF_SLOTS; + goto fail2; + } + memcpy(model->name, normalized, namelen + 1); model->registration_sequence = registration_sequence; |