Skip to content

Proxying certain [Serializable] classes produces proxy types that fail PEVerify test #367

@stakx

Description

@stakx

Using Castle Core 4.2.1, proxying the following type (or System.Security.Claims.ClaimsIdentity, if you want a more realistic example) produces a proxy class with incorrect IL:

[Serializable]
public class BadSerializable
{
    public BadSerializable() { }
    public BadSerializable(SerializationInfo info, StreamingContext context) { }
    public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { }
}

generator.CreateClassProxy<BadSerializable>(...);

When running PEVerify for the dynamically generated assembly, it complains about duplicate methods:

[MD]: Error: Method has a duplicate, token=0x06000004. [token:0x06000003]
[MD]: Error: Method has a duplicate, token=0x06000003. [token:0x06000004]
2 Error(s) Verifying Castle.Core\src\Castle.Core.Tests\bin\Debug\net461\CastleDynProxy2.dll

The mentioned methods belong to the generated proxy class BadSerializableProxy.

Below you'll find the two methods as ILSpy decompiles them back to C#:

// Castle.Proxies.BadSerializableProxy (method token 06000003):
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
    BadSerializable_GetObjectData badSerializable_GetObjectData = new BadSerializable_GetObjectData(typeof(SerializableClassTestCase.BadSerializable), this, this.__interceptors, BadSerializableProxy.token_GetObjectData, new object[]
    {
        info,
        context
    });
    badSerializable_GetObjectData.Proceed();
}

// Castle.Proxies.BadSerializableProxy (method token 06000004):
public override void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
{
    Type type = Type.GetType("Castle.DynamicProxy.Serialization.ProxyObjectReference, Castle.Core, Version=0.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc", true, false);
    serializationInfo.SetType(type);
    serializationInfo.AddValue("__interceptors", this.__interceptors);
    string[] value = new string[0];
    serializationInfo.AddValue("__interfaces", value);
    serializationInfo.AddValue("__baseType", "Castle.DynamicProxy.Tests.SerializableClassTestCase+BadSerializable, Castle.Core.Tests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc");
    serializationInfo.AddValue("__proxyGenerationOptions", BadSerializableProxy.proxyGenerationOptions);
    serializationInfo.AddValue("__proxyTypeId", "class");
    serializationInfo.AddValue("__delegateToBase", false);
    MemberInfo[] array = FormatterServices.GetSerializableMembers(typeof(SerializableClassTestCase.BadSerializable));
    array = TypeUtil.Sort(array);
    object[] objectData = FormatterServices.GetObjectData(this, array);
    serializationInfo.AddValue("__data", objectData);
}

This error does not happen if either:

  • the class is not decorated with [Serializable]
  • implements the ISerializable interface
  • GetObjectData is not declared virtual

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions