gpRank_t: Prevent overflow in stored rank

Resolves most of #772.
- Match maximum size of levels array to ROUNDQUEUE_MAX, to prevent edge cases
- Explicitly check that numLevels does not equal/exceed array size before writing
This commit is contained in:
toaster 2023-11-19 16:33:16 +00:00
parent 68d057c4b3
commit 66844457cd
4 changed files with 11 additions and 4 deletions

View file

@ -36,6 +36,10 @@ extern "C" {
// Selected map etc.
// =============================
#define ROUNDQUEUE_MAX 10 // sane max? maybe make dynamically allocated later
#define ROUNDQUEUE_CLEAR UINT16_MAX // lives in gametype field of packets
// The roundqueue itself is resident in g_game.h
// Selected by user.
extern INT16 gamemap;
extern char mapmusname[7];

View file

@ -54,9 +54,6 @@ typedef enum
NEXTMAP_SPECIAL = NEXTMAP_INVALID
} nextmapspecial_t;
#define ROUNDQUEUE_MAX 10 // sane max? maybe make dynamically allocated later
#define ROUNDQUEUE_CLEAR UINT16_MAX // lives in gametype field of packets
struct roundentry_t
{
UINT16 mapnum; // Map number at this position

View file

@ -364,6 +364,12 @@ void K_InitGrandPrixRank(gpRank_t *rankData)
--------------------------------------------------*/
void gpRank_t::Update(void)
{
if (numLevels >= ROUNDQUEUE_MAX)
{
CONS_Alert(CONS_ERROR, "gpRank_t::Update(): Too many courses recorded in rank, discarding this round");
return;
}
gpRank_level_t *const lvl = &levels[numLevels];
prisons += numtargets;

View file

@ -62,7 +62,7 @@ struct gpRank_t
boolean specialWon;
UINT8 numLevels;
gpRank_level_t levels[CUPCACHE_PODIUM];
gpRank_level_t levels[ROUNDQUEUE_MAX];
#ifdef __cplusplus
void Init(void);