2009-08-29 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Sat, 29 Aug 2009 21:18:23 +0000 (21:18 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Sat, 29 Aug 2009 21:18:23 +0000 (21:18 -0000)
* metadata-verify.c: Verify for duplicated types.

svn path=/trunk/mono/; revision=140926

mono/metadata/ChangeLog
mono/metadata/metadata-verify.c

index c58e216ebc4a8b85941294be8d891f44e3df1409..eda8728be254df8206c69140f40447fe873adae1 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-29  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * metadata-verify.c: Verify for duplicated types.
+
 2009-08-28  Rodrigo Kumpera  <rkumpera@novell.com>
 
        * metadata-verify.c (verify_typedef_table): Verify for nested types
index 61a00c69ee7c613fe6ded94b1c2f5974ae2c5e18..10ba4650ecb82c577008ca1c53f322702fb95cf7 100644 (file)
@@ -250,6 +250,13 @@ typedef struct {
                } \
        } while (0)
 
+#define ADD_ERROR_NO_RETURN(__ctx, __msg)      \
+       do {    \
+               if ((__ctx)->report_error) \
+                       ADD_VERIFY_INFO(__ctx, __msg, MONO_VERIFY_ERROR, MONO_EXCEPTION_INVALID_PROGRAM); \
+               (__ctx)->valid = 0; \
+       } while (0)
+
 #define ADD_ERROR(__ctx, __msg)        \
        do {    \
                if ((__ctx)->report_error) \
@@ -3217,6 +3224,74 @@ verify_generic_param_constraint_table (VerifyContext *ctx)
        }
 }
 
+
+typedef struct {
+       const char *name;
+       const char *name_space;
+       guint32 resolution_scope;
+} TypeDefUniqueId;
+
+static guint
+typedef_hash (gconstpointer _key)
+{
+       const TypeDefUniqueId *key = _key;
+       return g_str_hash (key->name) ^ g_str_hash (key->name_space) ^ key->resolution_scope; /*XXX better salt the int key*/
+}
+
+static gboolean
+typedef_equals (gconstpointer _a, gconstpointer _b)
+{
+       const TypeDefUniqueId *a = _a;
+       const TypeDefUniqueId *b = _b;
+       return !strcmp (a->name, b->name) && !strcmp (a->name_space, b->name_space) && a->resolution_scope == b->resolution_scope;
+}
+
+static void
+verify_typedef_table_global_constraints (VerifyContext *ctx)
+{
+       int i;
+       guint32 data [MONO_TYPEDEF_SIZE];
+       guint32 nested_data [MONO_NESTED_CLASS_SIZE];
+       MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_TYPEDEF];
+       MonoTableInfo *nested_table = &ctx->image->tables [MONO_TABLE_NESTEDCLASS];
+       GHashTable *unique_types = g_hash_table_new_full (&typedef_hash, &typedef_equals, g_free, NULL);
+
+       for (i = 0; i < table->rows; ++i) {
+               guint visibility;
+               TypeDefUniqueId *type = g_new (TypeDefUniqueId, 1);
+               mono_metadata_decode_row (table, i, data, MONO_TYPEDEF_SIZE);
+
+               type->name = mono_metadata_string_heap (ctx->image, data [MONO_TYPEDEF_NAME]);
+               type->name_space = mono_metadata_string_heap (ctx->image, data [MONO_TYPEDEF_NAMESPACE]);
+               type->resolution_scope = 0;
+
+               visibility = data [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+               if (visibility >= TYPE_ATTRIBUTE_NESTED_PUBLIC && visibility <= TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM) {
+                       int res = search_sorted_table (ctx, MONO_TABLE_NESTEDCLASS, MONO_NESTED_CLASS_NESTED, i + 1);
+                       g_assert (res >= 0);
+
+                       mono_metadata_decode_row (nested_table, res, nested_data, MONO_NESTED_CLASS_SIZE);
+                       type->resolution_scope = nested_data [MONO_NESTED_CLASS_ENCLOSING];
+               }
+
+               if (g_hash_table_lookup (unique_types, type)) {
+                       ADD_ERROR_NO_RETURN (ctx, g_strdup_printf ("TypeDef table row %d has duplicate for tupe (%s,%s,%x)", i, type->name, type->name_space, type->resolution_scope));
+                       g_hash_table_destroy (unique_types);
+                       g_free (type);
+                       return;
+               }
+               g_hash_table_insert (unique_types, type, GUINT_TO_POINTER (1));
+       }
+
+       g_hash_table_destroy (unique_types);
+}
+
+static void
+verify_tables_data_global_constraints (VerifyContext *ctx)
+{
+       verify_typedef_table_global_constraints (ctx);
+}
+       
 static void
 verify_tables_data (VerifyContext *ctx)
 {
@@ -3307,6 +3382,8 @@ verify_tables_data (VerifyContext *ctx)
        verify_method_spec_table (ctx);
        CHECK_ERROR ();
        verify_generic_param_constraint_table (ctx);
+       CHECK_ERROR ();
+       verify_tables_data_global_constraints (ctx);
 }
 
 static void