Fix invalid instantiations on method calls.
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 30 May 2011 18:58:27 +0000 (15:58 -0300)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 30 May 2011 18:58:27 +0000 (15:58 -0300)
* verify.c: Disalow GTDs on method position.

Fixes #656913

mono/metadata/verify.c
mono/tests/verifier/invalid_broken_method_inst.il [new file with mode: 0644]
mono/tests/verifier/invalid_broken_type_inst.il [new file with mode: 0644]

index 93b34350a0e5cc7444dfe38bfc2170beaf8d901d..c10b5038b36be7a1752f3c7cc4b45c6747bb5c2c 100644 (file)
@@ -6,6 +6,7 @@
  *
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Rodrigo Kumpera
  */
 #include <config.h>
 
@@ -775,12 +776,13 @@ is_valid_type_in_context (VerifyContext *ctx, MonoType *type)
 }
 
 static gboolean
-is_valid_generic_instantiation_in_context (VerifyContext *ctx, MonoGenericInst *ginst)
+is_valid_generic_instantiation_in_context (VerifyContext *ctx, MonoGenericInst *ginst, gboolean check_gtd)
 {
        int i;
        for (i = 0; i < ginst->type_argc; ++i) {
                MonoType *type = ginst->type_argv [i];
-               if (!is_valid_type_in_context (ctx, type))
+                       
+               if (!mono_type_is_valid_type_in_context_full (type, ctx->generic_context, TRUE))
                        return FALSE;
        }
        return TRUE;
@@ -837,7 +839,7 @@ mono_method_is_valid_generic_instantiation (VerifyContext *ctx, MonoMethod *meth
        MonoGenericContainer *gc = mono_method_get_generic_container (gmethod->declaring);
        if (!gc) /*non-generic inflated method - it's part of a generic type  */
                return TRUE;
-       if (ctx && !is_valid_generic_instantiation_in_context (ctx, ginst))
+       if (ctx && !is_valid_generic_instantiation_in_context (ctx, ginst, TRUE))
                return FALSE;
        return is_valid_generic_instantiation (gc, &gmethod->context, ginst);
 
@@ -849,7 +851,7 @@ mono_class_is_valid_generic_instantiation (VerifyContext *ctx, MonoClass *klass)
        MonoGenericClass *gklass = klass->generic_class;
        MonoGenericInst *ginst = gklass->context.class_inst;
        MonoGenericContainer *gc = gklass->container_class->generic_container;
-       if (ctx && !is_valid_generic_instantiation_in_context (ctx, ginst))
+       if (ctx && !is_valid_generic_instantiation_in_context (ctx, ginst, TRUE))
                return FALSE;
        return is_valid_generic_instantiation (gc, &gklass->context, ginst);
 }
diff --git a/mono/tests/verifier/invalid_broken_method_inst.il b/mono/tests/verifier/invalid_broken_method_inst.il
new file mode 100644 (file)
index 0000000..c5fc73f
--- /dev/null
@@ -0,0 +1,48 @@
+.assembly extern mscorlib
+{
+  .ver 4:0:0:0
+  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+}
+
+
+.assembly 'test'
+{
+  .hash algorithm 0x00008004
+  .ver  0:0:0:0
+}
+.module test.dll
+
+.class public Generic<T>
+{
+       .method public hidebysig specialname rtspecialname  instance default void '.ctor' ()  cil managed 
+       {
+               .maxstack 8
+               ldarg.0 
+               call instance void object::'.ctor'()
+               ret 
+       }
+
+       .method public static void Method2 () {
+               ret
+       }
+}
+
+.class public Generic2<T>
+{
+}
+
+.class public auto ansi beforefieldinit Base extends [mscorlib]System.Object
+{
+       .method public static void Method<T> () {
+               ret
+       }
+
+       .method public static hidebysig void Main ()
+       {
+               .entrypoint
+               call void class Generic<class Generic2>::Method2 ()
+               //call void Base::Method<Generic> ()
+       
+               ret
+       }
+}
diff --git a/mono/tests/verifier/invalid_broken_type_inst.il b/mono/tests/verifier/invalid_broken_type_inst.il
new file mode 100644 (file)
index 0000000..d729f66
--- /dev/null
@@ -0,0 +1,48 @@
+.assembly extern mscorlib
+{
+  .ver 4:0:0:0
+  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+}
+
+
+.assembly 'test'
+{
+  .hash algorithm 0x00008004
+  .ver  0:0:0:0
+}
+.module test.dll
+
+.class public Generic<T>
+{
+       .method public hidebysig specialname rtspecialname  instance default void '.ctor' ()  cil managed 
+       {
+               .maxstack 8
+               ldarg.0 
+               call instance void object::'.ctor'()
+               ret 
+       }
+
+       .method public static void Method2 () {
+               ret
+       }
+}
+
+.class public Generic2<T>
+{
+}
+
+.class public auto ansi beforefieldinit Base extends [mscorlib]System.Object
+{
+       .method public static void Method<T> () {
+               ret
+       }
+
+       .method public static hidebysig void Main ()
+       {
+               .entrypoint
+               //call void class Generic<class Generic2>::Method2 ()
+               call void Base::Method<Generic> ()
+       
+               ret
+       }
+}