2009-11-25 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 25 Nov 2009 19:31:09 +0000 (19:31 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Wed, 25 Nov 2009 19:31:09 +0000 (19:31 -0000)
* loader.c (field_from_memberref): Resolve the class first then the field
signature. Remove a lot of duplicated code and make sure we don't pass valid
values to mono_loader_set_error_field_load.

Fixes #553306.

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

mono/metadata/ChangeLog
mono/metadata/loader.c

index a293f435b2dcfa82326da43ba08d7fc5e5405752..726e262e71d84e64390201f66efdfa0cd495edbb 100644 (file)
@@ -1,3 +1,11 @@
+2009-11-25  Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * loader.c (field_from_memberref): Resolve the class first then the field
+       signature. Remove a lot of duplicated code and make sure we don't pass valid
+       values to mono_loader_set_error_field_load.
+
+       Fixes #553306.
+
 2009-11-25  Rodrigo Kumpera  <rkumpera@novell.com>
 
        * class.c (inflate_generic_type): Change code to use new signature of
index 5c5e4d1f2c81fe63a80dac2e4689f4fd311d49a1..6293811e7dc1176ca7ab4ba3b1aa040f63306ee6 100644 (file)
@@ -417,7 +417,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
        MonoTableInfo *tables = image->tables;
        MonoType *sig_type;
        guint32 cols[6];
-       guint32 nindex, class;
+       guint32 nindex, class, class_table;
        const char *fname;
        const char *ptr;
        guint32 idx = mono_metadata_token_index (token);
@@ -433,13 +433,40 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
                return NULL;
        }
 
+       switch (class) {
+       case MONO_MEMBERREF_PARENT_TYPEDEF:
+               class_table = MONO_TOKEN_TYPE_DEF;
+               klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | nindex);
+               break;
+       case MONO_MEMBERREF_PARENT_TYPEREF:
+               class_table = MONO_TOKEN_TYPE_REF;
+               klass = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | nindex);
+               break;
+       case MONO_MEMBERREF_PARENT_TYPESPEC:
+               class_table = MONO_TOKEN_TYPE_SPEC;
+               klass = mono_class_get_full (image, MONO_TOKEN_TYPE_SPEC | nindex, context);
+               break;
+       default:
+               /*FIXME this must set a loader error!*/
+               g_warning ("field load from %x", class);
+               return NULL;
+       }
+
+       if (!klass) {
+               char *name = mono_class_name_from_token (image, class_table | nindex);
+               g_warning ("Missing field %s in class %s (type token %d)", fname, name, class_table | nindex);
+               mono_loader_set_error_type_load (name, image->assembly_name);
+               g_free (name);
+               return NULL;
+       }
+
        ptr = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
        mono_metadata_decode_blob_size (ptr, &ptr);
        /* we may want to check the signature here... */
 
        if (*ptr++ != 0x6) {
                g_warning ("Bad field signature class token %08x field name %s token %08x", class, fname, token);
-               mono_loader_set_error_field_load (NULL, fname);
+               mono_loader_set_error_field_load (klass, fname);
                return NULL;
        }
        /* FIXME: This needs a cache, especially for generic instances, since
@@ -449,60 +476,16 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass,
        if (!sig_type) {
                sig_type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
                if (sig_type == NULL) {
-                       mono_loader_set_error_field_load (NULL, fname);
+                       mono_loader_set_error_field_load (klass, fname);
                        return NULL;
                }
                sig_type = cache_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE], sig_type);
        }
 
-       switch (class) {
-       case MONO_MEMBERREF_PARENT_TYPEDEF:
-               klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | nindex);
-               if (!klass) {
-                       char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_DEF | nindex);
-                       g_warning ("Missing field %s in class %s (typedef index %d)", fname, name, nindex);
-                       mono_loader_set_error_type_load (name, image->assembly_name);
-                       g_free (name);
-                       return NULL;
-               }
-               mono_class_init (klass);
-               if (retklass)
-                       *retklass = klass;
-               field = mono_class_get_field_from_name_full (klass, fname, sig_type);
-               break;
-       case MONO_MEMBERREF_PARENT_TYPEREF:
-               klass = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | nindex);
-               if (!klass) {
-                       char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_REF | nindex);
-                       g_warning ("missing field %s in class %s (typeref index %d)", fname, name, nindex);
-                       mono_loader_set_error_type_load (name, image->assembly_name);
-                       g_free (name);
-                       return NULL;
-               }
-               mono_class_init (klass);
-               if (retklass)
-                       *retklass = klass;
-               field = mono_class_get_field_from_name_full (klass, fname, sig_type);
-               break;
-       case MONO_MEMBERREF_PARENT_TYPESPEC: {
-               klass = mono_class_get_full (image, MONO_TOKEN_TYPE_SPEC | nindex, context);
-               if (!klass) {
-                       char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_REF | nindex);
-                       g_warning ("missing field %s in class %s (typeref index %d)", fname, name, nindex);
-                       mono_loader_set_error_type_load (name, image->assembly_name);
-                       g_free (name);
-                       return NULL;
-               }
-               mono_class_init (klass); /*FIXME is this really necessary?*/
-               if (retklass)
-                       *retklass = klass;
-               field = mono_class_get_field_from_name_full (klass, fname, sig_type);
-               break;
-       }
-       default:
-               g_warning ("field load from %x", class);
-               return NULL;
-       }
+       mono_class_init (klass); /*FIXME is this really necessary?*/
+       if (retklass)
+               *retklass = klass;
+       field = mono_class_get_field_from_name_full (klass, fname, sig_type);
 
        if (!field)
                mono_loader_set_error_field_load (klass, fname);