add PR_StringValid and PR_EdictValid to check the validity of progs string

and entity values without crashing.
This commit is contained in:
Bill Currie 2002-10-29 05:07:10 +00:00
parent 4ad8ed1fc2
commit aa36b85ba6
3 changed files with 34 additions and 8 deletions

View file

@ -107,6 +107,7 @@ int PR_AccessField (progs_t *pr, const char *name, etype_t type,
edict_t *EDICT_NUM(progs_t *pr, int n);
int NUM_FOR_EDICT(progs_t *pr, edict_t *e);
int NUM_FOR_BAD_EDICT(progs_t *pr, edict_t *e);
qboolean PR_EdictValid (progs_t *pr, int e);
#define NEXT_EDICT(p,e) ((edict_t *)( (byte *)e + (p)->pr_edict_size))
@ -204,6 +205,7 @@ void PR_InitRuntime (progs_t *pr);
// PR Strings stuff
//
qboolean PR_StringValid (progs_t *pr, int num);
char *PR_GetString(progs_t *pr, int num);
int PR_SetString(progs_t *pr, const char *s);
void PR_GarbageCollect (progs_t *pr);

View file

@ -545,3 +545,13 @@ NUM_FOR_EDICT (progs_t *pr, edict_t *e)
return b;
}
qboolean
PR_EdictValid (progs_t *pr, int e)
{
if (e < 0 || e >= pr->pr_edictareasize)
return false;
if (e % pr->pr_edict_size)
return false;
return true;
}

View file

@ -193,24 +193,38 @@ PR_GarbageCollect (progs_t *pr)
}
}
char *
PR_GetString (progs_t *pr, int num)
static inline char *
get_string (progs_t *pr, unsigned int num)
{
if (num < 0) {
int row = ~num / 1024;
if ((int) num < 0) {
unsigned int row = ~num / 1024;
num = ~num % 1024;
if (row < 0 || row >= pr->dyn_str_size)
goto bad_string_offset;
if (row >= pr->dyn_str_size)
return 0;
return pr->dynamic_strings[row][num].string;
} else {
if (num >= pr->pr_stringsize)
goto bad_string_offset;
return 0;
return pr->pr_strings + num;
}
}
bad_string_offset:
qboolean
PR_StringValid (progs_t *pr, int num)
{
return get_string (pr, num) != 0;
}
char *
PR_GetString (progs_t *pr, int num)
{
char *str;
str = get_string (pr, num);
if (str)
return str;
PR_RunError (pr, "Invalid string offset %u", num);
}