leejw51 / protobuf-net

Automatically exported from code.google.com/p/protobuf-net
0 stars 0 forks source link

NullReferenceException in CompilerContext.EmitCall() when serializing arrays of nullable elements #217

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Happening in v2 beta 431. Code to reproduce:

[ProtoContract]
public class FooRow
{
    [ProtoMember(1)]
    public int?[] Items;
}

var row = new FooRow {Items = new int?[] {42, null, null, null }};
using (var stream = new MemoryStream())
    Serializer.Serialize(stream, row);

I'm not sure if protobuf-net is supposed to support nullable types or not, but 
it throws the following exception which is definitely a bug:

System.NullReferenceException: Object reference not set to an instance of an 
object.
at ProtoBuf.Compiler.CompilerContext.EmitCall(MethodInfo method) in 
C:\Dev\protobuf-net\protobuf-net\Compiler\CompilerContext.cs: line 462
at ProtoBuf.Serializers.ArrayDecorator.EmitRead(CompilerContext ctx, Local 
valueFrom) in C:\Dev\protobuf-net\protobuf-net\Serializers\ArrayDecorator.cs: 
line 233
at 
ProtoBuf.Serializers.ProtoDecoratorBase.ProtoBuf.Serializers.IProtoSerializer.Em
itRead(CompilerContext ctx, Local valueFrom) in 
C:\Dev\protobuf-net\protobuf-net\Serializers\ProtoDecoratorBase.cs: line 18
at ProtoBuf.Compiler.CompilerContext.ReadNullCheckedTail(Type type, 
IProtoSerializer tail, Local valueFrom) in 
C:\Dev\protobuf-net\protobuf-net\Compiler\CompilerContext.cs: line 549
at ProtoBuf.Serializers.FieldDecorator.EmitRead(CompilerContext ctx, Local 
valueFrom) in C:\Dev\protobuf-net\protobuf-net\Serializers\FieldDecorator.cs: 
line 55
at 
ProtoBuf.Serializers.ProtoDecoratorBase.ProtoBuf.Serializers.IProtoSerializer.Em
itRead(CompilerContext ctx, Local valueFrom) in 
C:\Dev\protobuf-net\protobuf-net\Serializers\ProtoDecoratorBase.cs: line 18
at ProtoBuf.Serializers.TypeSerializer.WriteFieldHandler(CompilerContext ctx, 
Type expected, Local loc, CodeLabel handler, CodeLabel continue, 
IProtoSerializer serializer) in 
C:\Dev\protobuf-net\protobuf-net\Serializers\TypeSerializer.cs: line 509
at 
ProtoBuf.Serializers.TypeSerializer.ProtoBuf.Serializers.IProtoSerializer.EmitRe
ad(CompilerContext ctx, Local valueFrom) in 
C:\Dev\protobuf-net\protobuf-net\Serializers\TypeSerializer.cs: line 455
at ProtoBuf.Compiler.CompilerContext.BuildDeserializer(IProtoSerializer head) 
in C:\Dev\protobuf-net\protobuf-net\Compiler\CompilerContext.cs: line 116
at ProtoBuf.Serializers.CompiledSerializer..ctor(IProtoTypeSerializer head) in 
C:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs: line 36
at ProtoBuf.Serializers.CompiledSerializer.Wrap(IProtoTypeSerializer head) in 
C:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs: line 24
at ProtoBuf.Meta.MetaType.get_Serializer() in 
C:\Dev\protobuf-net\protobuf-net\Meta\MetaType.cs: line 211
at ProtoBuf.Meta.RuntimeTypeModel.Serialize(Int32 key, Object value, 
ProtoWriter dest) in C:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs: 
line 357
at ProtoBuf.Meta.TypeModel.SerializeCore(ProtoWriter writer, Object value) in 
C:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs: line 139
at ProtoBuf.Meta.TypeModel.Serialize(Stream dest, Object value, 
SerializationContext context) in 
C:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs: line 166
at ProtoBuf.Serializer.Serialize(Stream destination, T instance) in 
C:\Dev\protobuf-net\protobuf-net\Serializer.cs: line 78
at Phoenix.Service.Specifications.IO.Foo.<.ctor>b__1() in 
MsgPackFormatterSpecifications.cs: line 82 

Original issue reported on code.google.com by rdingw...@gmail.com on 8 Aug 2011 at 6:14

GoogleCodeExporter commented 9 years ago
Nullable values are on the edge of what the underlying spec can define; for 
properties etc null is interpreted as "do not serialize". Inside 
collections/arrays, it cannot handle nulls as there would be no spec-compliant 
way to express that on the wire.

Original comment by marc.gravell on 8 Aug 2011 at 6:53

GoogleCodeExporter commented 9 years ago
This is fixed in current trunk, **HOWEVER**, protobuf has no direct support for 
nulls. There is a new optional mechanism for this ("SupportNulls") which *if 
enabled* will allow nulls in lists/arrays to be captured, **but** it is a 
breaking change for that member (and requires a very small amount of overhead 
per item).

Original comment by marc.gravell on 2 Nov 2011 at 9:59

GoogleCodeExporter commented 9 years ago
Hi there,
I am using a string[] and would like to keep the null values inside the array. 
You mentioned that SupportNull option but I couldn't find how to enable that 
behaviour. If I try to set attributes on the ProtoMember, I can see the 
IsPacked, IsRequired, OverwriteLists booleans but SupportNull does not appear.. 
I just grabbed the r480.
Please can you advice how to use it?
Many thanks.

Original comment by edward.a...@bigjimmyindustries.com on 14 Dec 2011 at 11:47

GoogleCodeExporter commented 9 years ago
I haven't documented that option yet (it was added as a specific request), but 
- *at the moment* you can only enable this via (for example):

    RuntimeTypeModel.Default[typeof (YourType)][3].SupportNull = true;

where 3 is the field-number.

This should probably be available on the attribute model too...

Original comment by marc.gravell on 14 Dec 2011 at 12:10

GoogleCodeExporter commented 9 years ago
It did it, Thank you so much!!

Original comment by edward.a...@bigjimmyindustries.com on 14 Dec 2011 at 12:38

GoogleCodeExporter commented 9 years ago
Any chance of this being added to the attribute model?

Original comment by j...@jdh28.co.uk on 14 Mar 2014 at 4:27

GoogleCodeExporter commented 9 years ago
Just had the same problem.
While I do understand that the protocol is not capeable of handling this 
(seriously google?), I do not understand that a nullref is thrown from deep 
inside your code.

What about adding a much more meaningfull Exception here? Something like 
ProtoBufProtocolException("Arrays and lists are not allowed to contain 
'null'-values.")?

Original comment by bastianm...@googlemail.com on 5 Aug 2014 at 9:17