Bug 19825 - Mono Reflection cannot handle Custom Attributes constructors that take Jagged Arrarys
Summary: Mono Reflection cannot handle Custom Attributes constructors that take Jagged...
Status: RESOLVED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: Reflection (show other bugs)
Version: 3.2.x
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-05-15 12:46 UTC by Michael Larson
Modified: 2014-05-15 15:33 UTC (History)
3 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments

Description Michael Larson 2014-05-15 12:46:54 UTC
When using reflection in Mono and passing a jagged array to a custom attribute the following error is thrown:

Type 0x1d not handled in custom attr array decoding

The reason I found this bug is that I was trying to use IKVM to load a Java class at runtime time in my C# application and it was crashing with the above exception. I contacted Jeroen Frijters the creator of IKVM and he was able to help me to track down the problem to mono/mono/metadata/reflection.c in the load_cattr_value function, line 8029. Here is the code in question:

case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
	for (i = 0; i < alen; i++) {
		MonoObject *item = load_cattr_value (image, &tklass->byval_arg, p, &p);
		mono_array_setref (arr, i, item);
	}
	break;
     default:
	g_error ("Type 0x%02x not handled in custom attr array decoding", basetype);
}

I found by adding MONO_TYPE_SZARRAY the case that is handled above everything works great:

case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_SZARRAY:
	for (i = 0; i < alen; i++) {
		MonoObject *item = load_cattr_value (image, &tklass->byval_arg, p, &p);
		mono_array_setref (arr, i, item);
	}
	break;
     default:
	g_error ("Type 0x%02x not handled in custom attr array decoding", basetype);
}

Jeroen was kind enough to also provide me with a isolated repo of this problem which is the following:

using System;
using System.Reflection;
using System.Reflection.Emit;

public class MyAttr : Attribute
{
    public MyAttr(string[][] data)
    {
        Console.WriteLine(data);
        Console.WriteLine(data[0][0]);
    }
}

class Program
{
    public static void Main()
    {
        var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Foo"), AssemblyBuilderAccess.Save);
        var modb = ab.DefineDynamicModule("Foo", "Foo.dll");
        var tb = modb.DefineType("T");
        tb.SetCustomAttribute(new CustomAttributeBuilder(typeof(MyAttr).GetConstructors()[0],
            new object[] { new string[][] { new string[] { "foo" } } }));
        tb.CreateType();
        ab.Save("Foo.dll");

        Type t = Assembly.Load("Foo").GetType("T");
        Console.WriteLine(t.GetCustomAttributes(false).Length);
    }
}
Comment 1 Zoltan Varga 2014-05-15 13:27:36 UTC
Fixed in mono master 8d9e02de313278eaf606145d4048801d7160a67b. Thanks for the report.
Comment 2 Michael Larson 2014-05-15 15:33:18 UTC
thanks for the quick response!

Note You need to log in before you can comment on or make changes to this bug.