From de01d34925cb609607e76b3cb7e7a48312f2cc8e Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 28 Apr 2012 03:53:23 -0400 Subject: [PATCH] type parsing for constants, globals and locals. Sanatize constants to select internal functions to prevent possible runtime issues that could be a result of atoi working for what we consider invalid strings containing constants. --- asm.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- data/test.qs | 5 ++++- gmqcc.h | 1 + util.c | 13 +++++++++++++ 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/asm.c b/asm.c index 99bb406..b1f4880 100644 --- a/asm.c +++ b/asm.c @@ -78,11 +78,34 @@ void asm_clear() { * are locals. */ static inline bool asm_parse_type(const char *skip, size_t line, asm_state *state) { - if (strstr(skip, "FLOAT:") == &skip[0]) { return true; } - if (strstr(skip, "VECTOR:") == &skip[0]) { return true; } - if (strstr(skip, "ENTITY:") == &skip[0]) { return true; } - if (strstr(skip, "FIELD:") == &skip[0]) { return true; } - if (strstr(skip, "STRING:") == &skip[0]) { return true; } + if (!(strstr(skip, "FLOAT:") == &skip[0]) && + (strstr(skip, "VECTOR:") == &skip[0]) && + (strstr(skip, "ENTITY:") == &skip[0]) && + (strstr(skip, "FIELD:") == &skip[0]) && + (strstr(skip, "STRING:") == &skip[0])) return false; + + /* TODO: determine if constant, global, or local */ + switch (*skip) { + /* VECTOR */ case 'V': { + const char *find = skip + 7; + while (*find == ' ' || *find == '\t') find++; + printf("found VECTOR %s\n", find); + break; + } + /* ENTITY */ case 'E': { + const char *find = skip + 7; + while (*find == ' ' || *find == '\t') find++; + printf("found ENTITY %s\n", find); + break; + } + /* STRING */ case 'S': { + const char *find = skip + 7; + while (*find == ' ' || *find == '\t') find++; + printf("found STRING %s\n", find); + break; + } + } + return false; } @@ -165,10 +188,19 @@ static inline bool asm_parse_func(const char *skip, size_t line, asm_state *stat code_chars_put(name, strlen(name)); code_chars_add('\0'); - /* TODO: sanatize `find` to ensure all numerical digits */ - - printf("found internal function %s, -%d\n", name, atoi(find)); + /* + * Sanatize the numerical constant used to select the + * internal function. Must ensure it's all numeric, since + * atoi can silently drop characters from a string and still + * produce a valid constant that would lead to runtime problems. + */ + if (util_strdigit(find)) + printf("found internal function %s, -%d\n", name, atoi(find)); + else + printf("invalid internal function identifier, must be all numeric\n"); + } else { + /* TODO: function bodies */ } mem_d(copy); diff --git a/data/test.qs b/data/test.qs index b26b4ef..14d3e26 100644 --- a/data/test.qs +++ b/data/test.qs @@ -82,4 +82,7 @@ FUNCTION: pow, $97 FUNCTION: findfloat, $98 FUNCTION: checkextension, $99 -; todo support other crap +; constants test +VECTOR: 1, 2, 3 +FLOAT: 1 +STRING: "hello world" diff --git a/gmqcc.h b/gmqcc.h index 6e66325..eca1e15 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -195,6 +195,7 @@ void util_memory_d (void *, unsigned int, const char *); void util_meminfo (); bool util_strupper (const char *); +bool util_strdigit (const char *); char *util_strdup (const char *); char *util_strrq (char *); char *util_strrnl (char *); diff --git a/util.c b/util.c index daf4b87..942f661 100644 --- a/util.c +++ b/util.c @@ -179,6 +179,19 @@ bool util_strupper(const char *str) { return true; } +/* + * Returns true if string is all digits, otherwise + * it returns false. + */ +bool util_strdigit(const char *str) { + while (*str) { + if(!isdigit(*str)) + return false; + str++; + } + return true; +} + void util_debug(const char *area, const char *ms, ...) { if (!opts_debug) return; -- 2.39.2