Merge pull request #2820 from kumpera/license-change-rebased
[mono.git] / mono / metadata / metadata.c
index 9c082de29c66488f90ab49aa65c04a25338ff2f0..b778e3964c6671db6efa1ab09eb69e10035b0521 100644 (file)
@@ -7,6 +7,7 @@
  *
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include <config.h>
@@ -1359,10 +1360,8 @@ mono_metadata_parse_array (MonoImage *m, const char *ptr, const char **rptr)
 {
        MonoError error;
        MonoArrayType *ret = mono_metadata_parse_array_internal (m, NULL, FALSE, ptr, rptr, &error);
-       if (!ret) {
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
-       }
+       mono_error_cleanup (&error);
+
        return ret;
 }
 
@@ -1743,22 +1742,6 @@ mono_metadata_parse_type_checked (MonoImage *m, MonoGenericContainer *container,
        return mono_metadata_parse_type_internal (m, container, opt_attrs, transient, ptr, rptr, error);
 }
 
-
-MonoType*
-mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container,
-                                                          short opt_attrs, const char *ptr, const char **rptr)
-{
-       MonoError error;
-       MonoType * type = mono_metadata_parse_type_internal (m, container, opt_attrs, FALSE, ptr, rptr, &error);
-       mono_loader_assert_no_error ();
-       if (!mono_error_ok (&error)) {
-               mono_loader_set_error_from_mono_error (&error);
-               mono_error_cleanup (&error);
-       }
-
-       return type;
-}
-
 /*
  * LOCKING: Acquires the loader lock.
  */
@@ -1766,7 +1749,10 @@ MonoType*
 mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
                          const char *ptr, const char **rptr)
 {
-       return mono_metadata_parse_type_full (m, NULL, opt_attrs, ptr, rptr);
+       MonoError error;
+       MonoType * type = mono_metadata_parse_type_internal (m, NULL, opt_attrs, FALSE, ptr, rptr, &error);
+       mono_error_cleanup (&error);
+       return type;
 }
 
 gboolean
@@ -1852,8 +1838,11 @@ mono_metadata_parse_signature (MonoImage *image, guint32 token)
        guint32 sig;
        const char *ptr;
 
-       if (image_is_dynamic (image))
-               return (MonoMethodSignature *)mono_lookup_dynamic_token (image, token, NULL);
+       if (image_is_dynamic (image)) {
+               ret = (MonoMethodSignature *)mono_lookup_dynamic_token (image, token, NULL, &error);
+               mono_error_raise_exception (&error); /* FIXME don't raise here */
+               return ret;
+       }
 
        g_assert (mono_metadata_token_table(token) == MONO_TABLE_STANDALONESIG);
                
@@ -2787,18 +2776,6 @@ free_inflated_method (MonoMethodInflated *imethod)
        if (method->signature)
                mono_metadata_free_inflated_signature (method->signature);
 
-       if (!((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))) {
-               MonoMethodHeader *header = imethod->header;
-
-               if (header) {
-                       /* Allocated in inflate_generic_header () */
-                       for (i = 0; i < header->num_locals; ++i)
-                               mono_metadata_free_type (header->locals [i]);
-                       g_free (header->clauses);
-                       g_free (header);
-               }
-       }
-
        g_free (method);
 }
 
@@ -3178,7 +3155,7 @@ get_anonymous_container_for_image (MonoImage *image, gboolean is_mvar)
 /*
  * mono_metadata_parse_generic_param:
  * @generic_container: Our MonoClass's or MonoMethod's MonoGenericContainer;
- *                     see mono_metadata_parse_type_full() for details.
+ *                     see mono_metadata_parse_type_checked() for details.
  * Internal routine to parse a generic type parameter.
  * LOCKING: Acquires the loader lock
  */
@@ -3400,6 +3377,10 @@ do_mono_metadata_parse_type (MonoType *type, MonoImage *m, MonoGenericContainer
                        return FALSE;
 
                type->data.klass = mono_class_from_mono_type (etype);
+
+               if (transient)
+                       mono_metadata_free_type (etype);
+
                g_assert (type->data.klass); //This was previously a check for NULL, but mcfmt should never fail. It can return a borken MonoClass, but should return at least something.
                break;
        }
@@ -3513,12 +3494,14 @@ hex_dump (const char *buffer, int base, int count)
  * @ptr: Points to the beginning of the Section Data (25.3)
  */
 static MonoExceptionClause*
-parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr)
+parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr, MonoError *error)
 {
        unsigned char sect_data_flags;
        int is_fat;
        guint32 sect_data_len;
        MonoExceptionClause* clauses = NULL;
+
+       mono_error_init (error);
        
        while (1) {
                /* align on 32-bit boundary */
@@ -3566,10 +3549,8 @@ parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr)
                                } else if (ec->flags == MONO_EXCEPTION_CLAUSE_NONE) {
                                        ec->data.catch_class = NULL;
                                        if (tof_value) {
-                                               MonoError error;
-                                               ec->data.catch_class = mono_class_get_checked (m, tof_value, &error);
-                                               if (!mono_error_ok (&error)) {
-                                                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                                               ec->data.catch_class = mono_class_get_checked (m, tof_value, error);
+                                               if (!is_ok (error)) {
                                                        g_free (clauses);
                                                        return NULL;
                                                }
@@ -3636,7 +3617,8 @@ mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *sum
                return FALSE;
 
        ptr = mono_image_rva_map (img, rva);
-       g_assert (ptr);
+       if (!ptr)
+               return FALSE;
 
        flags = *(const unsigned char *)ptr;
        format = flags & METHOD_HEADER_FORMAT_MASK;
@@ -3674,7 +3656,7 @@ mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *sum
  * Returns: a transient MonoMethodHeader allocated from the heap.
  */
 MonoMethodHeader *
-mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, const char *ptr)
+mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, const char *ptr, MonoError *error)
 {
        MonoMethodHeader *mh = NULL;
        unsigned char flags = *(const unsigned char *) ptr;
@@ -3687,7 +3669,12 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
        MonoTableInfo *t = &m->tables [MONO_TABLE_STANDALONESIG];
        guint32 cols [MONO_STAND_ALONE_SIGNATURE_SIZE];
 
-       g_return_val_if_fail (ptr != NULL, NULL);
+       mono_error_init (error);
+
+       if (!ptr) {
+               mono_error_set_bad_image (error, m, "Method header with null pointer");
+               return NULL;
+       }
 
        switch (format) {
        case METHOD_HEADER_TINY_FORMAT:
@@ -3725,20 +3712,28 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
                ptr = (char*)code + code_size;
                break;
        default:
+               mono_error_set_bad_image (error, m, "Invalid method header format %d", format);
                return NULL;
        }
 
        if (local_var_sig_tok) {
                int idx = (local_var_sig_tok & 0xffffff)-1;
-               if (idx >= t->rows || idx < 0)
+               if (idx >= t->rows || idx < 0) {
+                       mono_error_set_bad_image (error, m, "Invalid method header local vars signature token 0x%8x", idx);
                        goto fail;
+               }
                mono_metadata_decode_row (t, idx, cols, 1);
 
-               if (!mono_verifier_verify_standalone_signature (m, cols [MONO_STAND_ALONE_SIGNATURE], NULL))
+               if (!mono_verifier_verify_standalone_signature (m, cols [MONO_STAND_ALONE_SIGNATURE], NULL)) {
+                       mono_error_set_bad_image (error, m, "Method header locals signature 0x%8x verification failed", idx);
+                       goto fail;
+               }
+       }
+       if (fat_flags & METHOD_HEADER_MORE_SECTS) {
+               clauses = parse_section_data (m, &num_clauses, (const unsigned char*)ptr, error);
+               if (!is_ok (error))
                        goto fail;
        }
-       if (fat_flags & METHOD_HEADER_MORE_SECTS)
-               clauses = parse_section_data (m, &num_clauses, (const unsigned char*)ptr);
        if (local_var_sig_tok) {
                const char *locals_ptr;
                int len=0, i;
@@ -3752,14 +3747,8 @@ mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, cons
                mh = (MonoMethodHeader *)g_malloc0 (MONO_SIZEOF_METHOD_HEADER + len * sizeof (MonoType*) + num_clauses * sizeof (MonoExceptionClause));
                mh->num_locals = len;
                for (i = 0; i < len; ++i) {
-                       MonoError error;
-                       mh->locals [i] = mono_metadata_parse_type_internal (m, container, 0, TRUE, locals_ptr, &locals_ptr, &error);
-                       if (!mono_error_ok (&error)) {
-                               mono_loader_set_error_from_mono_error (&error);
-                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
-                       }
-
-                       if (!mh->locals [i])
+                       mh->locals [i] = mono_metadata_parse_type_internal (m, container, 0, TRUE, locals_ptr, &locals_ptr, error);
+                       if (!is_ok (error))
                                goto fail;
                }
        } else {
@@ -3798,7 +3787,10 @@ fail:
 MonoMethodHeader *
 mono_metadata_parse_mh (MonoImage *m, const char *ptr)
 {
-       return mono_metadata_parse_mh_full (m, NULL, ptr);
+       MonoError error;
+       MonoMethodHeader *header = mono_metadata_parse_mh_full (m, NULL, ptr, &error);
+       mono_error_cleanup (&error);
+       return header;
 }
 
 /*
@@ -3933,7 +3925,10 @@ mono_method_header_get_clauses (MonoMethodHeader *header, MonoMethod *method, gp
 MonoType *
 mono_metadata_parse_field_type (MonoImage *m, short field_flags, const char *ptr, const char **rptr)
 {
-       return mono_metadata_parse_type (m, MONO_PARSE_FIELD, field_flags, ptr, rptr);
+       MonoError error;
+       MonoType * type = mono_metadata_parse_type_internal (m, NULL, field_flags, FALSE, ptr, rptr, &error);
+       mono_error_cleanup (&error);
+       return type;
 }
 
 /**
@@ -3949,7 +3944,10 @@ mono_metadata_parse_field_type (MonoImage *m, short field_flags, const char *ptr
 MonoType *
 mono_metadata_parse_param (MonoImage *m, const char *ptr, const char **rptr)
 {
-       return mono_metadata_parse_type (m, MONO_PARSE_PARAM, 0, ptr, rptr);
+       MonoError error;
+       MonoType * type = mono_metadata_parse_type_internal (m, NULL, 0, FALSE, ptr, rptr, &error);
+       mono_error_cleanup (&error);
+       return type;
 }
 
 /*
@@ -5894,7 +5892,7 @@ handle_enum:
                        *conv = MONO_MARSHAL_CONV_DEL_FTN;
                        return MONO_NATIVE_FUNC;
                }
-               if (mono_defaults.safehandle_class && type->data.klass == mono_defaults.safehandle_class){
+               if (mono_class_try_get_safehandle_class () && type->data.klass == mono_class_try_get_safehandle_class ()){
                        *conv = MONO_MARSHAL_CONV_SAFEHANDLE;
                        return MONO_NATIVE_INT;
                }