From: Dale Weiler <killfieldengine@gmail.com>
Date: Sat, 28 Apr 2012 07:53:23 +0000 (-0400)
Subject: type parsing for constants, globals and locals.  Sanatize constants to select interna... 
X-Git-Tag: 0.1-rc1~578^2
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=de01d34925cb609607e76b3cb7e7a48312f2cc8e;p=xonotic%2Fgmqcc.git

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.
---

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;