Skip to content

[mono] DefineDynamicAssembly ignores PublicKeyToken #58015

@uweigand

Description

@uweigand

Description

Running the aspnetcore Microsoft.AspNetCore.Server.Kestrel.Core.Tests unit tests on Mono fails with:

    Microsoft.AspNetCore.Server.Kestrel.Core.Tests.Http1ConnectionTests.ConsumesRequestWhenApplicationDoesNotConsumeIt [FAIL]
      System.MethodAccessException : Method `Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody..ctor(Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol)' is inaccessible from method `Castle.Proxies.MessageBodyProxy..ctor(Castle.DynamicProxy.IInterceptor[],Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol)'
      Stack Trace:
           at Castle.Proxies.MessageBodyProxy..ctor(IInterceptor[] , HttpProtocol context)
        /home/uweigand/runtime/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs(862,0): at System.Reflection.RuntimeConstructorInfo.InternalInvoke(Object obj, Object[] parameters, Boolean wrapExceptions)
        /home/uweigand/runtime/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs(846,0): at System.Reflection.RuntimeConstructorInfo.DoInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
        /home/uweigand/runtime/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.cs(888,0): at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
        /home/uweigand/runtime/src/mono/System.Private.CoreLib/src/System/RuntimeType.Mono.cs(1499,0): at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
        /home/uweigand/runtime/src/libraries/System.Private.CoreLib/src/System/Activator.RuntimeType.cs(36,0): at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
        /home/uweigand/runtime/src/libraries/System.Private.CoreLib/src/System/Activator.cs(31,0): at System.Activator.CreateInstance(Type type, Object[] args)
           at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)
           at Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
           at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments)
           at Moq.Mock`1[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody, Microsoft.AspNetCore.Server.Kestrel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].InitializeInstancePexProtected()
           at Moq.PexProtector.Invoke(Action action)
           at Moq.Mock`1[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody, Microsoft.AspNetCore.Server.Kestrel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].InitializeInstance()
           at Moq.Mock`1[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody, Microsoft.AspNetCore.Server.Kestrel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].OnGetObject()
           at Moq.Mock.get_Object()
           at Moq.Mock`1[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.MessageBody, Microsoft.AspNetCore.Server.Kestrel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].get_Object()
        /home/uweigand/aspnetcore/src/Servers/Kestrel/Core/test/Http1ConnectionTests.cs(951,0): at Microsoft.AspNetCore.Server.Kestrel.Core.Tests.Http1ConnectionTests.ConsumesRequestWhenApplicationDoesNotConsumeIt()

Configuration

.NET 6 Preview7 re-built for the linux-s390x target (using the Mono runtime by default).

Regression?

Probably not.

Other information

The access check fails because the dynamic assembly generated by the Castle.DynamicProxy framework does not have a public key token defined. More specifically, the AssemblyName passed to DefineDynamicAssembly does have the token (which is why the code works with the CoreCLR runtime), but that is simply ignored by the Mono implementation.

Note that the managed part of the implementation does not currently even pass the full AssemblyName to the C implementation in the Mono VM, but only some portions of it (Name, Version, and CultureInfo.Name). Adding code to also pass the public key token and then install it as the token of the new assembly in C code seems to fix this problem, the test case then passes.

I'll submit a PR shortly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions