Merge pull request #2720 from mono/fix-39325
[mono.git] / mono / mini / genmdesc.c
index d00a24b54558c9f617a646f4b9768014bd53a6bd..7118e19c8cec06cd9fb7588d5e7c89f2e9564706 100644 (file)
@@ -54,6 +54,14 @@ static GHashTable *template_table;
 
 #define eat_whitespace(s) while (*(s) && isspace (*(s))) s++;
 
+// Per spec isalnum() expects input in the range 0-255
+// and can misbehave if you pass in a signed char.
+static int
+isalnum_char(char c)
+{
+       return isalnum ((unsigned char)c);
+}
+
 static int
 load_file (const char *name) {
        FILE *f;
@@ -99,7 +107,7 @@ load_file (const char *name) {
                        is_template = TRUE;
                        desc = g_new0 (OpDesc, 1);
                } else {
-                       desc = g_hash_table_lookup (table, str);
+                       desc = (OpDesc *)g_hash_table_lookup (table, str);
                        if (!desc)
                                g_error ("Invalid opcode '%s' at line %d in %s\n", str, line, name);
                        if (desc->desc)
@@ -140,8 +148,12 @@ load_file (const char *name) {
                                */
                        } else if (strncmp (p, "len:", 4) == 0) {
                                unsigned long size;
+                               char* endptr;
                                p += 4;
-                               size = strtoul (p, &p, 10);
+                               size = strtoul (p, &endptr, 10);
+                               if (size == 0 && p == endptr)
+                                       g_error ("Invalid length '%s' at line %d in %s\n", p, line, name);
+                               p = endptr;
                                if (!nacl_length_set) {
                                        desc->spec [MONO_INST_LEN] = size;
                                }
@@ -159,9 +171,9 @@ load_file (const char *name) {
                                OpDesc *tdesc;
                                p += 9;
                                tname = p;
-                               while (*p && isalnum (*p)) ++p;
+                               while (*p && isalnum_char (*p)) ++p;
                                *p++ = 0;
-                               tdesc = g_hash_table_lookup (template_table, tname);
+                               tdesc = (OpDesc *)g_hash_table_lookup (template_table, tname);
                                if (!tdesc)
                                        g_error ("Invalid template name %s at '%s' at line %d in %s\n", tname, p, line, name);
                                for (i = 0; i < MONO_INST_MAX; ++i) {
@@ -177,7 +189,7 @@ load_file (const char *name) {
                                        g_error ("Duplicated name tag in template %s at '%s' at line %d in %s\n", desc->name, p, line, name);
                                p += 5;
                                tname = p;
-                               while (*p && isalnum (*p)) ++p;
+                               while (*p && isalnum_char (*p)) ++p;
                                *p++ = 0;
                                if (g_hash_table_lookup (template_table, tname))
                                        g_error ("Duplicated template %s at line %d in %s\n", tname, line, name);
@@ -216,10 +228,10 @@ init_table (void) {
 
 static void
 output_char (FILE *f, char c) {
-       if (isalnum (c))
+       if (isalnum_char (c))
                fprintf (f, "%c", c);
        else
-               fprintf (f, "\\x%x\" \"", c);
+               fprintf (f, "\\x%x\" \"", (guint8)c);
 }
 
 static void
@@ -234,13 +246,13 @@ build_table (const char *fname, const char *name) {
        if (!(f = fopen (fname, "w")))
                g_error ("Cannot open file '%s'", fname);
        fprintf (f, "/* File automatically generated by genmdesc, don't change */\n\n");
-       fprintf (f, "const char %s [] = {\n", name);
+       fprintf (f, "const char mono_%s [] = {\n", name);
        fprintf (f, "\t\"");
        for (j = 0; j < MONO_INST_MAX; ++j)
                fprintf (f, "\\x0");
        fprintf (f, "\"\t/* null entry */\n");
        idx = 1;
-       g_string_append_printf (idx_array, "const guint16 %s_idx [] = {\n", name);
+       g_string_append_printf (idx_array, "const guint16 mono_%s_idx [] = {\n", name);
 
        for (i = OP_LOAD; i < OP_LAST; ++i) {
                desc = opcodes + i;