phanductrieu / protobuf-net

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

Nullable<Enum> not DEserialized correctly #266

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Please include an e-mail address if this might need a dialogue!
==============

What steps will reproduce the problem?
1. Run attached test - it will fail
2.
3.

What is the expected output? What do you see instead?
> Serialized NULL of type Nullable<T> should be deserialized as NULL for any 
'T'.

What version of the product are you using? On what operating system?
> v2 r480

Please provide any additional information below.
> It looks like behavior of NullDecorator.Read not match behavior of 
TryDeserializeAuxiliaryType.
> Here we always get at least default(T):
        protected internal override object Deserialize(int key, object value, ProtoReader source)
        {
            //Helpers.DebugWriteLine("Deserialize", value);
            IProtoSerializer ser = ((MetaType)types[key]).Serializer;
            if (value == null && Helpers.IsValueType(ser.ExpectedType)) {
                return ser.Read(Activator.CreateInstance(ser.ExpectedType), source); <-- !!!
            } else {
                return ser.Read(value, source);
            }
        }
        public override object Read(object value, ProtoReader source)
        {
            SubItemToken tok = ProtoReader.StartSubItem(source);
            int field;
            while((field = source.ReadFieldHeader()) > 0)
            {
                if(field == Tag) {
                    value = Tail.Read(value, source);
                } else {
                    source.SkipField();
                }
            }
            ProtoReader.EndSubItem(tok, source);
            return value; <-- !!!
        }
> But TryDeserializeAuxiliaryType will just return NULL (it is expected).

Original issue reported on code.google.com by vadim.sk...@gmail.com on 23 Jan 2012 at 3:03

Attachments:

GoogleCodeExporter commented 9 years ago
Now I think that problem is in this code:

        private object DeserializeCore(ProtoReader reader, Type type, object value, bool noAutoCreate)
        {
            int key = GetKey(ref type);
            if (key >= 0)
            {
                return Deserialize(key, value, reader);
            }
            // this returns true to say we actively found something, but a value is assigned either way (or throws)
            TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, ref value, true, false, noAutoCreate, false);
            return value;
        }

As you can see 'autoCreate' parameter (which called 'noAutoCreate' by mistake) 
not passed to Deserialize() so default value for all value-types (including 
enums) will be created. But inside the TryDeserializeAuxiliaryType() it is only 
created for 'autoCreate=true' case.

P.S.: I put all my fixes to github - see 
https://github.com/vadimskipin/protobuf-net for details.
P.P.S.: It is very sad that there is no official github mirror :(

Original comment by vadim.sk...@gmail.com on 24 Jan 2012 at 8:07

GoogleCodeExporter commented 9 years ago
Fixed as side-effect of 265, in r481

Original comment by marc.gravell on 24 Jan 2012 at 11:37

GoogleCodeExporter commented 9 years ago
In debug build we have failed debug assertion in EnumSerializer.cs:

        public object Read(object value, ProtoReader source)
        {
            Helpers.DebugAssert(value == null); // since replaces
            ...

Again, it looks like 'ser.Read(Activator.CreateInstance(ser.ExpectedType), 
source)' line in RuntimeTypeMode.cs is the cause of problem.

Original comment by vadim.sk...@gmail.com on 25 Jan 2012 at 12:49

GoogleCodeExporter commented 9 years ago
...and assertion in TagDecarator.cs:

        public override object Read(object value, ProtoReader source)
        {
            Helpers.DebugAssert(fieldNumber == source.FieldNumber);
            ...

Original comment by vadim.sk...@gmail.com on 25 Jan 2012 at 1:27

GoogleCodeExporter commented 9 years ago
Darn - will check 

Original comment by marc.gravell on 25 Jan 2012 at 3:31

GoogleCodeExporter commented 9 years ago
The first part is fixed next build; do you have a repro for the tagdecorator 
issue?

Original comment by marc.gravell on 29 Feb 2012 at 2:31