From aa36b85ba60724e01aafe84a992583f67981d826 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 29 Oct 2002 05:07:10 +0000 Subject: [PATCH] add PR_StringValid and PR_EdictValid to check the validity of progs string and entity values without crashing. --- include/QF/progs.h | 2 ++ libs/gamecode/engine/pr_edict.c | 10 ++++++++++ libs/gamecode/engine/pr_strings.c | 30 ++++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/QF/progs.h b/include/QF/progs.h index 845e4c154..87b0d59fb 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -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); diff --git a/libs/gamecode/engine/pr_edict.c b/libs/gamecode/engine/pr_edict.c index fd1cfe658..78fafd41a 100644 --- a/libs/gamecode/engine/pr_edict.c +++ b/libs/gamecode/engine/pr_edict.c @@ -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; +} diff --git a/libs/gamecode/engine/pr_strings.c b/libs/gamecode/engine/pr_strings.c index e905a4756..67cf9a3ba 100644 --- a/libs/gamecode/engine/pr_strings.c +++ b/libs/gamecode/engine/pr_strings.c @@ -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); }