[runtime] Fail gracefully when method has conflicting attributes
authorAlexander Kyte <alexmkyte@gmail.com>
Tue, 14 Feb 2017 18:30:36 +0000 (13:30 -0500)
committerAlexander Kyte <alexmkyte@gmail.com>
Mon, 20 Feb 2017 00:44:13 +0000 (19:44 -0500)
mono/metadata/marshal.c
mono/metadata/marshal.h
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c

index 6020bf50eb45f2a18f5fe5295728ccbee8d9572d..76f38e399d861bfb4d679bfc2072ecdb8bb23a9e 100644 (file)
@@ -426,7 +426,9 @@ mono_delegate_to_ftnptr (MonoDelegate *delegate)
                target_handle = mono_gchandle_new_weakref (delegate->target, FALSE);
        }
 
-       wrapper = mono_marshal_get_managed_wrapper (method, klass, target_handle);
+       wrapper = mono_marshal_get_managed_wrapper (method, klass, target_handle, &error);
+       if (!is_ok (&error))
+               goto fail;
 
        delegate->delegate_trampoline = mono_compile_method_checked (wrapper, &error);
        if (!is_ok (&error))
@@ -8659,9 +8661,8 @@ mono_marshal_set_callconv_from_modopt (MonoMethod *method, MonoMethodSignature *
  * If target_handle==0, the wrapper info will be a WrapperInfo structure.
  */
 MonoMethod *
-mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, uint32_t target_handle)
+mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, uint32_t target_handle, MonoError *error)
 {
-       MonoError error;
        MonoMethodSignature *sig, *csig, *invoke_sig;
        MonoMethodBuilder *mb;
        MonoMethod *res, *invoke;
@@ -8672,7 +8673,12 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
        EmitMarshalContext m;
 
        g_assert (method != NULL);
-       g_assert (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL));
+       mono_error_init (error);
+
+       if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
+               mono_error_set_invalid_program (error, "Failed because method (%s) marked PInvokeCallback (managed method) and extern (unmanaged) simultaneously.", mono_method_full_name (method, TRUE));
+               return NULL;
+       }
 
        /* 
         * FIXME: Should cache the method+delegate type pair, since the same method
@@ -8726,8 +8732,8 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass,
                 * contents of the attribute without constructing it, as that might not be
                 * possible when running in cross-compiling mode.
                 */
-               cinfo = mono_custom_attrs_from_class_checked (delegate_klass, &error);
-               mono_error_assert_ok (&error);
+               cinfo = mono_custom_attrs_from_class_checked (delegate_klass, error);
+               mono_error_assert_ok (error);
                attr = NULL;
                if (cinfo) {
                        for (i = 0; i < cinfo->num_attrs; ++i) {
index e00661b1b593604f318b93cd47064c7fab2362fa..4b1c185f876011751b95773b1a031527dd3342ad 100644 (file)
@@ -330,7 +330,7 @@ MonoMethodSignature*
 mono_marshal_get_string_ctor_signature (MonoMethod *method);
 
 MonoMethod *
-mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, uint32_t this_loc);
+mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, uint32_t this_loc, MonoError *exernal_error);
 
 gpointer
 mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type);
index 6e91638d881fe1f3f3f97a4cf2c9d97e12c9555b..6d4f50a42388fb4e9641557cf720f6c0756f0c50 100644 (file)
@@ -4330,7 +4330,9 @@ add_wrappers (MonoAotCompile *acfg)
                                        named += slen;
                                }
 
-                               wrapper = mono_marshal_get_managed_wrapper (method, klass, 0);
+                               wrapper = mono_marshal_get_managed_wrapper (method, klass, 0, &error);
+                               mono_error_assert_ok (&error);
+
                                add_method (acfg, wrapper);
                                if (export_name)
                                        g_hash_table_insert (acfg->export_names, wrapper, export_name);
index ed2b485a626d415b54fda77ef970106282fca802..85990d353ab31e4691c3aa969d833a488cab0d12 100644 (file)
@@ -1214,7 +1214,9 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        klass = decode_klass_ref (module, p, &p, error);
                        if (!klass)
                                return FALSE;
-                       ref->method = mono_marshal_get_managed_wrapper (m, klass, 0);
+                       ref->method = mono_marshal_get_managed_wrapper (m, klass, 0, error);
+                       if (!mono_error_ok (error))
+                               return FALSE;
                        break;
                }
                default: