msgpack / msgpack-cli

MessagePack implementation for Common Language Infrastructure / msgpack.org[C#]
http://msgpack.org
Apache License 2.0
835 stars 175 forks source link

GetMemberName() causes NullReferenceException when using MessagePackSerializer.Get<T>() in Xamarin iOS #334

Open JesperTreetop opened 5 years ago

JesperTreetop commented 5 years ago

Steps to reproduce

  1. Create an iOS App in Visual Studio for Mac.
  2. Add a package reference to MsgPack.Cli.
  3. Add the following model:
    public class ExampleModel {
        [MessagePackMember(0, Name = "examples")]
        public string Example { get; set; }
    }
  4. Add the following code:
    var x = MessagePackSerializer.Get<ExampleModel>();

Results

A crash with:

System.NullReferenceException: Object reference not set to an instance of an object
  at System.Reflection.CustomAttributeNamedArgument.get_MemberInfo () [0x00030] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corert/src/System.Private.CoreLib/src/System/Reflection/CustomAttributeNamedArgument.cs:80 
  at MsgPack.ReflectionAbstractions.GetMemberName (System.Reflection.CustomAttributeNamedArgument source) [0x00000] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPack.Serialization.SerializationTarget.GetAttributeProperty (System.String attributeName, System.Reflection.CustomAttributeData attribute, System.String propertyName) [0x00025] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPack.Serialization.SerializationTarget+<>c.<GetAnnotatedMembersWithDuplicationDetection>b__38_1 (System.Reflection.MemberInfo member) [0x0003d] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at (wrapper delegate-invoke) System.Func`2[System.Reflection.MemberInfo,MsgPack.Serialization.SerializingMember].invoke_TResult_T(System.Reflection.MemberInfo)
  at System.Linq.Enumerable+SelectArrayIterator`2[TSource,TResult].ToArray () [0x00012] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corefx/src/System.Linq/src/System/Linq/Select.cs:240 
  at System.Linq.Buffer`1[TElement]..ctor (System.Collections.Generic.IEnumerable`1[T] source) [0x0000a] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corefx/src/System.Linq/src/System/Linq/Buffer.cs:33 
  at System.Linq.OrderedEnumerable`1[TElement].ToArray () [0x00000] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corefx/src/System.Linq/src/System/Linq/OrderedEnumerable.cs:34 
  at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x0000e] in /Users/builder/jenkins/workspace/xamarin-macios/xamarin-macios/external/mono/external/corefx/src/System.Linq/src/System/Linq/ToCollection.cs:18 
  at MsgPack.Serialization.SerializationTarget.Prepare (MsgPack.Serialization.SerializationContext context, System.Type targetType) [0x00043] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPack.Serialization.MessagePackSerializer.CreateReflectionInternal[T] (MsgPack.Serialization.SerializationContext context, System.Type concreteType, MsgPack.Serialization.PolymorphismSchema schema) [0x000be] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPack.Serialization.MessagePackSerializer.CreateInternal[T] (MsgPack.Serialization.SerializationContext context, MsgPack.Serialization.PolymorphismSchema schema) [0x0009c] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPack.Serialization.SerializationContext.GetSerializer[T] (System.Object providerParameter) [0x00109] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPack.Serialization.MessagePackSerializer.Get[T] (MsgPack.Serialization.SerializationContext context, System.Object providerParameter) [0x0000e] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPack.Serialization.MessagePackSerializer.Get[T] (MsgPack.Serialization.SerializationContext context) [0x00000] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPack.Serialization.MessagePackSerializer.Get[T] () [0x00005] in <78757c4a7a9d40249bcf74135a5d8e10>:0 
  at MsgPackBugTest.AppDelegate.FinishedLaunching (UIKit.UIApplication application, Foundation.NSDictionary launchOptions) [0x00002] in /Users/jesper/Projects/MsgPackBugTest/MsgPackBugTest/AppDelegate.cs:19 

The crash seems to be caused by this line:

var property = attribute.GetNamedArguments().SingleOrDefault( a => a.GetMemberName() == propertyName );
if ( property.GetMemberName() == null )
{
    // Use default.
    return null;
}

The property type, CustomAttributeNamedArgument, is a struct, and when the named argument can't be found (in this case, NilImplication), GetMemberName() runs on a default(CustomAttributeNamedArgument).

There is a fix existing in the codebase to handle this case, but because of various #ifs being used, the version that's being used by Mono does not have this fix. It appears that this version is being pulled in instead, likely due to Mono not being possible to target for NuGet packages. Inserting the same fix in the other branch would solve the issue.

Limited workaround

This exact instance can be worked around by specifying all named arguments used in GetAnnotatedMembersWithDuplicationDetection on all attributes. In other words, this:

    public class ExampleModel {
        [MessagePackMember(0, Name = "examples", NilImplication = NilImplication.Null)]
        public string Example { get; set; }
    }

doesn't throw. However, it is tedious and if there's a named argument/property added at some point, it will likely crash in the same way. Additionally, it seems that this issue recurs all over the place where any MsgPack.Cli attribute can be used, so it's hard not to run into.

Versions used

=== Visual Studio Community 2019 for Mac ===

Version 8.3.6 (build 4) Installation UUID: 687b26fe-e715-4df4-ac1c-280184e1a76a GTK+ 2.24.23 (Raleigh theme) Xamarin.Mac 5.16.1.24 (d16-3 / 08809f5b)

Package version: 604000208

=== Mono Framework MDK ===

Runtime: Mono 6.4.0.208 (2019-06/07c23f2ca43) (64-bit) Package version: 604000208

=== NuGet ===

Version: 5.3.0.6192

=== .NET Core SDK ===

SDK: /usr/local/share/dotnet/sdk/3.0.100/Sdks SDK Versions: 3.0.100 3.0.100-preview8-013656 2.2.300 2.2.103 2.1.505 2.1.401 2.1.300-preview2-008533 2.1.300-preview1-008174 2.1.4 2.0.0 2.0.0-preview2-006497 2.0.0-preview1-005977 1.0.1 1.0.0-rc4-004771 1.0.0-preview2-1-003177 1.0.0-preview2-003121 1.0.0-preview1-002702 MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/6.4.0/lib/mono/msbuild/Current/bin/Sdks

=== .NET Core Runtime ===

Runtime: /usr/local/share/dotnet/dotnet Runtime Versions: 3.0.0 3.0.0-preview8-28405-07 2.2.5 2.2.1 2.1.13 2.1.9 2.1.3 2.1.0-preview2-26406-04 2.1.0-preview1-26216-03 2.0.5 2.0.0 2.0.0-preview2-25407-01 2.0.0-preview1-002111-00 1.1.1 1.1.0 1.0.4 1.0.3 1.0.0 1.0.0-rc2-3002702

=== Xamarin.Profiler ===

Version: 1.6.12.29 Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Updater ===

Version: 11

=== Xamarin.Android ===

Not Installed

=== Microsoft Mobile OpenJDK ===

Java SDK: Not Found

Android Designer EPL code available here: https://github.com/xamarin/AndroidDesigner.EPL

=== Android SDK Manager ===

Version: 1.4.0.65 Hash: c33b107 Branch: remotes/origin/d16-3 Build date: 2019-10-10 12:15:44 UTC

=== Android Device Manager ===

Version: 1.2.0.116 Hash: d2b2af0 Branch: remotes/origin/d16-3 Build date: 2019-10-10 12:16:06 UTC

=== Xamarin Inspector ===

Version: 1.4.3 Hash: db27525 Branch: 1.4-release Build date: Mon, 09 Jul 2018 21:20:18 GMT Client compatibility: 1

=== Apple Developer Tools ===

Xcode 11.2 (15519) Build 11B44

=== Xamarin.Mac ===

Version: 6.4.0.2 (Visual Studio Community) Hash: e37549bc Branch: xcode11.1 Build date: 2019-10-07 22:43:23-0400

=== Xamarin.iOS ===

Version: 13.4.0.2 (Visual Studio Community) Hash: e37549bc Branch: xcode11.1 Build date: 2019-10-07 22:43:23-0400

=== Xamarin Designer ===

Version: 16.3.0.247 Hash: 52eac1a9e Branch: remotes/origin/d16-3 Build date: 2019-10-03 23:04:28 UTC

=== Build Information ===

Release ID: 803060004 Git revision: 081f7b8bbd534cb73bbfb5cff3d9aa4907396a4f Build date: 2019-10-31 17:10:49+00 Build branch: release-8.3 Xamarin extensions: ade6d975df7634a5d81feda320a6102e5bacf309

=== Operating System ===

Mac OS X 10.15.1 Darwin 19.0.0 Darwin Kernel Version 19.0.0 Thu Oct 17 16:17:15 PDT 2019 root:xnu-6153.41.3~29/RELEASE_X86_64 x86_64