Skip to content

MessagePack.Formatters.TypelessFormatter.DeserializeByTypeName may throw NRE #1422

@tmat

Description

@tmat

Bug description

 MessagePack.MessagePackSerializationException: Failed to deserialize Microsoft.CodeAnalysis.CodeCleanup.CodeCleanupOptions value.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
      at Deserialize(Object[] , MessagePackReader& , MessagePackSerializerOptions )
      at MessagePack.Internal.AnonymousSerializableFormatter`1.Deserialize(MessagePackReader& reader, MessagePackSerializerOptions options)
      at lambda_method(Closure , Object , MessagePackReader& , MessagePackSerializerOptions )
      at MessagePack.Formatters.TypelessFormatter.DeserializeByTypeName(ArraySegment`1 typeName, MessagePackReader& byteSequence, MessagePackSerializerOptions options)
      at MessagePack.Formatters.TypelessFormatter.Deserialize(MessagePackReader& reader, MessagePackSerializerOptions options)
      at MessagePack.Formatters.ForceTypelessFormatter`1.Deserialize(MessagePackReader& reader, MessagePackSerializerOptions options)
      at Deserialize(Object[] , MessagePackReader& , MessagePackSerializerOptions )
      at MessagePack.Internal.AnonymousSerializableFormatter`1.Deserialize(MessagePackReader& reader, MessagePackSerializerOptions options)
      at MessagePack.MessagePackSerializer.Deserialize[T](MessagePackReader& reader, MessagePackSerializerOptions options)
   --- End of inner exception stack trace ---
      at MessagePack.MessagePackSerializer.Deserialize[T](MessagePackReader& reader, MessagePackSerializerOptions options)
      at lambda_method(Closure , MessagePackReader& , MessagePackSerializerOptions )
      at MessagePack.MessagePackSerializer.Deserialize(Type type, MessagePackReader& reader, MessagePackSerializerOptions options)
      at StreamJsonRpc.MessagePackFormatter.JsonRpcResult.SetExpectedResultType(Type resultType)
   --- End of stack trace from previous location where exception was thrown ---
      at StreamJsonRpc.MessagePackFormatter.JsonRpcResult.GetResult[T]()

The type that fails to deserialize:

[DataContract]
internal readonly record struct CodeCleanupOptions(
    [property: DataMember(Order = 0)] SyntaxFormattingOptions FormattingOptions,
    [property: DataMember(Order = 1)] SimplifierOptions SimplifierOptions,
    [property: DataMember(Order = 2)] AddImportPlacementOptions AddImportOptions);

SyntaxFormattingOptions and SimplifierOptions are abstract classes for which we use typeless formatters:

new ForceTypelessFormatter<SimplifierOptions>()
new ForceTypelessFormatter<SyntaxFormattingOptions>()

Repro steps

Couldn't find a straightforward repro.
This exception only occurs when running Roslyn tests in src\EditorFeatures\CSharpTest\ConvertTupleToStruct\ConvertTupleToStructTests.cs without the debugger attached (somehow it matters) with change dotnet/roslyn#60803 (commit a5f13b9ef96c136f913d363b3c200e0cb574bef0).

What happened instead of what you expected.

  • Version used: 2.3.0.0
  • Runtime: .NET Framework

Additional context

image

BTW, when the CodeCleanupOptions struct is changed to a class and new ForceTypelessFormatter<CodeCleanupOptions>() is added to the formatters the serialization fails with stack overflow:

>	System.Buffers.dll!System.Buffers.DefaultArrayPool<byte>.Rent(int minimumLength)	Unknown
 	MessagePack.dll!Nerdbank.Streams.Sequence<byte>.GetSegment(int sizeHint)	Unknown
 	MessagePack.dll!Nerdbank.Streams.Sequence<byte>.GetMemory(int sizeHint)	Unknown
 	MessagePack.dll!MessagePack.Utilities.GetMemoryCheckResult<byte>(System.Buffers.IBufferWriter<byte> bufferWriter, int size)	Unknown
 	MessagePack.dll!MessagePack.BufferWriter.BufferWriter(System.Buffers.IBufferWriter<byte> output)	Unknown
 	MessagePack.dll!MessagePack.MessagePackWriter.MessagePackWriter(System.Buffers.IBufferWriter<byte> writer)	Unknown
 	MessagePack.dll!MessagePack.MessagePackWriter.Clone(System.Buffers.IBufferWriter<byte> writer)	Unknown
 	MessagePack.dll!MessagePack.Formatters.TypelessFormatter.Serialize(ref MessagePack.MessagePackWriter writer, object value, MessagePack.MessagePackSerializerOptions options)	Unknown
 	MessagePack.dll!MessagePack.Formatters.ForceTypelessFormatter<System.__Canon>.Serialize(ref MessagePack.MessagePackWriter writer, System.__Canon value, MessagePack.MessagePackSerializerOptions options)	Unknown
 	[Lightweight Function]	
 	MessagePack.dll!MessagePack.Formatters.TypelessFormatter.Serialize(ref MessagePack.MessagePackWriter writer, object value, MessagePack.MessagePackSerializerOptions options)	Unknown
 	[The 3 frame(s) above this were repeated 3164 times]	
 	MessagePack.dll!MessagePack.Formatters.ForceTypelessFormatter<System.__Canon>.Serialize(ref MessagePack.MessagePackWriter writer, System.__Canon value, MessagePack.MessagePackSerializerOptions options)	Unknown
 	MessagePack.dll!MessagePack.MessagePackSerializer.Serialize<Microsoft.CodeAnalysis.CodeCleanup.CodeCleanupOptions>(ref MessagePack.MessagePackWriter writer, Microsoft.CodeAnalysis.CodeCleanup.CodeCleanupOptions value, MessagePack.MessagePackSerializerOptions options)	Unknown
 	[Lightweight Function]	
 	MessagePack.dll!MessagePack.MessagePackSerializer.Serialize(System.Type type, ref MessagePack.MessagePackWriter writer, object obj, MessagePack.MessagePackSerializerOptions options)	Unknown
 	StreamJsonRpc.dll!StreamJsonRpc.MessagePackFormatter.JsonRpcResultFormatter.Serialize(ref MessagePack.MessagePackWriter writer, StreamJsonRpc.Protocol.JsonRpcResult value, MessagePack.MessagePackSerializerOptions options)	Unknown
 	StreamJsonRpc.dll!StreamJsonRpc.MessagePackFormatter.JsonRpcMessageFormatter.Serialize(ref MessagePack.MessagePackWriter writer, StreamJsonRpc.Protocol.JsonRpcMessage value, MessagePack.MessagePackSerializerOptions options)	Unknown
 	StreamJsonRpc.dll!StreamJsonRpc.MessagePackFormatter.Serialize(System.Buffers.IBufferWriter<byte> contentBuffer, StreamJsonRpc.Protocol.JsonRpcMessage message)	Unknown
 	StreamJsonRpc.dll!StreamJsonRpc.LengthHeaderMessageHandler.Write(StreamJsonRpc.Protocol.JsonRpcMessage content, System.Threading.CancellationToken cancellationToken)	Unknown
 	StreamJsonRpc.dll!StreamJsonRpc.PipeMessageHandler.WriteCoreAsync(StreamJsonRpc.Protocol.JsonRpcMessage content, System.Threading.CancellationToken cancellationToken)	Unknown
 	StreamJsonRpc.dll!StreamJsonRpc.MessageHandlerBase.WriteAsync(StreamJsonRpc.Protocol.JsonRpcMessage content, System.Threading.CancellationToken cancellationToken)	Unknown
 	StreamJsonRpc.dll!StreamJsonRpc.JsonRpc.SendAsync(StreamJsonRpc.Protocol.JsonRpcMessage message, System.Threading.CancellationToken cancellationToken)	Unknown
 	StreamJsonRpc.dll!StreamJsonRpc.JsonRpc.HandleRpcAsync(StreamJsonRpc.Protocol.JsonRpcMessage rpc)	Unknown

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions