Skip to content

Commit d8b65b8

Browse files
committed
Fix some collection built in serializer bypass null check. #211
This commit is imported from 0.8.1 branch. Some built-in serializers use UnpackFromCore instead of UnpackFrom for items deserialization. This causes bypass of null check, then null items are deserialized as non-null objects.
1 parent 8862324 commit d8b65b8

6 files changed

Lines changed: 88 additions & 17 deletions

CHANGES.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,11 @@ Release 0.8.0
599599

600600
Nothing from 0.8.0 beta.
601601

602+
Release 0.8.1 2017/02/02
603+
604+
BUG FIXES
605+
* Fix null items of complex type in List<T> or Dictionary<TKey, TValue> will not be deserialized as null. Issue #211.
606+
602607
Release 0.9.0 beta1 2016/09/24
603608

604609
NEW FEATURES
@@ -635,4 +640,5 @@ Release 0.9.0 (planned)
635640
* Fix a combination of readonly members and collection members incorrect code generation when the type also have deserialization constructor. Issue #207.
636641
* Fix Windows Native build error. Issue #206.
637642
* Fix built-in collection serializers such as List<T> serializer causes SecurityException when the program run in restricted environment like Silverlight. Issue #205.
643+
* Fix null items of complex type in List<T> or Dictionary<TKey, TValue> will not be deserialized as null. Issue #211. (from 0.8.1)
638644

src/MsgPack/Serialization/DefaultSerializers/System_Collections_Generic_Dictionary_2MessagePackSerializer`2.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,12 @@ private void UnpackToCore( Unpacker unpacker, Dictionary<TKey, TValue> collectio
103103
{
104104
using ( var subTreeUnpacker = unpacker.ReadSubtree() )
105105
{
106-
key = this._keySerializer.UnpackFromCore( subTreeUnpacker );
106+
key = this._keySerializer.UnpackFrom( subTreeUnpacker );
107107
}
108108
}
109109
else
110110
{
111-
key = this._keySerializer.UnpackFromCore( unpacker );
111+
key = this._keySerializer.UnpackFrom( unpacker );
112112
}
113113

114114
if ( !unpacker.Read() )
@@ -120,12 +120,12 @@ private void UnpackToCore( Unpacker unpacker, Dictionary<TKey, TValue> collectio
120120
{
121121
using ( var subTreeUnpacker = unpacker.ReadSubtree() )
122122
{
123-
collection.Add( key, this._valueSerializer.UnpackFromCore( subTreeUnpacker ) );
123+
collection.Add( key, this._valueSerializer.UnpackFrom( subTreeUnpacker ) );
124124
}
125125
}
126126
else
127127
{
128-
collection.Add( key, this._valueSerializer.UnpackFromCore( unpacker ) );
128+
collection.Add( key, this._valueSerializer.UnpackFrom( unpacker ) );
129129
}
130130
}
131131
}
@@ -180,12 +180,12 @@ private async Task UnpackToAsyncCore( Unpacker unpacker, Dictionary<TKey, TValue
180180
{
181181
using ( var subTreeUnpacker = unpacker.ReadSubtree() )
182182
{
183-
key = await this._keySerializer.UnpackFromAsyncCore( subTreeUnpacker, cancellationToken ).ConfigureAwait( false );
183+
key = await this._keySerializer.UnpackFromAsync( subTreeUnpacker, cancellationToken ).ConfigureAwait( false );
184184
}
185185
}
186186
else
187187
{
188-
key = await this._keySerializer.UnpackFromAsyncCore( unpacker, cancellationToken ).ConfigureAwait( false );
188+
key = await this._keySerializer.UnpackFromAsync( unpacker, cancellationToken ).ConfigureAwait( false );
189189
}
190190

191191
if ( !unpacker.Read() )
@@ -197,12 +197,12 @@ private async Task UnpackToAsyncCore( Unpacker unpacker, Dictionary<TKey, TValue
197197
{
198198
using ( var subTreeUnpacker = unpacker.ReadSubtree() )
199199
{
200-
collection.Add( key, await this._valueSerializer.UnpackFromAsyncCore( subTreeUnpacker, cancellationToken ).ConfigureAwait( false ) );
200+
collection.Add( key, await this._valueSerializer.UnpackFromAsync( subTreeUnpacker, cancellationToken ).ConfigureAwait( false ) );
201201
}
202202
}
203203
else
204204
{
205-
collection.Add( key, await this._valueSerializer.UnpackFromAsyncCore( unpacker, cancellationToken ).ConfigureAwait( false ) );
205+
collection.Add( key, await this._valueSerializer.UnpackFromAsync( unpacker, cancellationToken ).ConfigureAwait( false ) );
206206
}
207207
}
208208
}

src/MsgPack/Serialization/DefaultSerializers/System_Collections_Generic_KeyValuePair_2MessagePackSerializer`2.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ protected internal override KeyValuePair<TKey, TValue> UnpackFromCore( Unpacker
6161
SerializationExceptions.ThrowUnexpectedEndOfStream( unpacker );
6262
}
6363

64-
var key = unpacker.LastReadData.IsNil ? default( TKey ) : this._keySerializer.UnpackFromCore( unpacker );
64+
var key = unpacker.LastReadData.IsNil ? default( TKey ) : this._keySerializer.UnpackFrom( unpacker );
6565

6666
if ( !unpacker.Read() )
6767
{
6868
SerializationExceptions.ThrowUnexpectedEndOfStream( unpacker );
6969
}
7070

71-
var value = unpacker.LastReadData.IsNil ? default( TValue ) : this._valueSerializer.UnpackFromCore( unpacker );
71+
var value = unpacker.LastReadData.IsNil ? default( TValue ) : this._valueSerializer.UnpackFrom( unpacker );
7272

7373
return new KeyValuePair<TKey, TValue>( key, value );
7474
}
@@ -89,14 +89,14 @@ protected internal override async Task<KeyValuePair<TKey, TValue>> UnpackFromAsy
8989
SerializationExceptions.ThrowUnexpectedEndOfStream( unpacker );
9090
}
9191

92-
var key = unpacker.LastReadData.IsNil ? default( TKey ) : await this._keySerializer.UnpackFromAsyncCore( unpacker, cancellationToken ).ConfigureAwait( false );
92+
var key = unpacker.LastReadData.IsNil ? default( TKey ) : await this._keySerializer.UnpackFromAsync( unpacker, cancellationToken ).ConfigureAwait( false );
9393

9494
if ( !await unpacker.ReadAsync( cancellationToken ).ConfigureAwait( false ) )
9595
{
9696
SerializationExceptions.ThrowUnexpectedEndOfStream( unpacker );
9797
}
9898

99-
var value = unpacker.LastReadData.IsNil ? default( TValue ) : await this._valueSerializer.UnpackFromAsyncCore( unpacker, cancellationToken ).ConfigureAwait( false );
99+
var value = unpacker.LastReadData.IsNil ? default( TValue ) : await this._valueSerializer.UnpackFromAsync( unpacker, cancellationToken ).ConfigureAwait( false );
100100

101101
return new KeyValuePair<TKey, TValue>( key, value );
102102
}

src/MsgPack/Serialization/DefaultSerializers/System_Collections_Generic_List_1MessagePackSerializer`1.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ private void UnpackToCore( Unpacker unpacker, List<T> collection, int count )
9999
{
100100
using ( var subTreeUnpacker = unpacker.ReadSubtree() )
101101
{
102-
collection.Add( this._itemSerializer.UnpackFromCore( subTreeUnpacker ) );
102+
collection.Add( this._itemSerializer.UnpackFrom( subTreeUnpacker ) );
103103
}
104104
}
105105
else
106106
{
107-
collection.Add( this._itemSerializer.UnpackFromCore( unpacker ) );
107+
collection.Add( this._itemSerializer.UnpackFrom( unpacker ) );
108108
}
109109
}
110110
}
@@ -158,12 +158,12 @@ private async Task UnpackToAsyncCore( Unpacker unpacker, List<T> collection, int
158158
{
159159
using ( var subTreeUnpacker = unpacker.ReadSubtree() )
160160
{
161-
collection.Add( await this._itemSerializer.UnpackFromAsyncCore( subTreeUnpacker, cancellationToken ).ConfigureAwait( false ) );
161+
collection.Add( await this._itemSerializer.UnpackFromAsync( subTreeUnpacker, cancellationToken ).ConfigureAwait( false ) );
162162
}
163163
}
164164
else
165165
{
166-
collection.Add( await this._itemSerializer.UnpackFromAsyncCore( unpacker, cancellationToken ).ConfigureAwait( false ) );
166+
collection.Add( await this._itemSerializer.UnpackFromAsync( unpacker, cancellationToken ).ConfigureAwait( false ) );
167167
}
168168
}
169169
}

src/MsgPack/Serialization/DefaultSerializers/System_Collections_Generic_Stack_1MessagePackSerializer`1.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ protected internal override async Task PackToAsyncCore( Packer packer, Stack<TIt
111111
await packer.PackArrayHeaderAsync( objectTree.Count, cancellationToken ).ConfigureAwait( false );
112112
foreach ( var item in objectTree )
113113
{
114-
await this._itemSerializer.PackToAsyncCore( packer, item, cancellationToken ).ConfigureAwait( false );
114+
await this._itemSerializer.PackToAsync( packer, item, cancellationToken ).ConfigureAwait( false );
115115
}
116116
}
117117

test/MsgPack.UnitTest/Serialization/RegressionTests.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,5 +381,70 @@ public void TestDateTimeTypeError_SerializationException()
381381
}
382382
}
383383
}
384+
385+
[Test]
386+
public void TestIssue211_ListOfT()
387+
{
388+
var target = new SerializationContext().GetSerializer<List<SingleValueObject>>();
389+
using ( var buffer = new MemoryStream() )
390+
{
391+
target.Pack( buffer, new List<SingleValueObject> { null } );
392+
buffer.Position = 0;
393+
var result = target.Unpack( buffer );
394+
Assert.That( result.Count, Is.EqualTo( 1 ) );
395+
Assert.That( result[ 0 ], Is.Null );
396+
}
397+
}
398+
399+
[Test]
400+
public void TestIssue211_DictionaryOfT()
401+
{
402+
var target = new SerializationContext().GetSerializer<Dictionary<string, SingleValueObject>>();
403+
using ( var buffer = new MemoryStream() )
404+
{
405+
target.Pack( buffer, new Dictionary<string, SingleValueObject> { { String.Empty, null } } );
406+
buffer.Position = 0;
407+
var result = target.Unpack( buffer );
408+
Assert.That( result.Count, Is.EqualTo( 1 ) );
409+
Assert.That( result.First().Value, Is.Null );
410+
}
411+
}
412+
413+
[Test]
414+
public void TestIssue211_StackOfT()
415+
{
416+
var target = new SerializationContext().GetSerializer<Stack<SingleValueObject>>();
417+
using ( var buffer = new MemoryStream() )
418+
{
419+
var obj = new Stack<SingleValueObject>();
420+
obj.Push( null );
421+
target.Pack( buffer, obj );
422+
buffer.Position = 0;
423+
var result = target.Unpack( buffer );
424+
Assert.That( result.Count, Is.EqualTo( 1 ) );
425+
Assert.That( result.Pop(), Is.Null );
426+
}
427+
}
428+
429+
[Test]
430+
public void TestIssue211_QueueOfT()
431+
{
432+
var target = new SerializationContext().GetSerializer<Queue<SingleValueObject>>();
433+
using ( var buffer = new MemoryStream() )
434+
{
435+
var obj = new Queue<SingleValueObject>();
436+
obj.Enqueue( null );
437+
target.Pack( buffer, obj );
438+
buffer.Position = 0;
439+
var result = target.Unpack( buffer );
440+
Assert.That( result.Count, Is.EqualTo( 1 ) );
441+
Assert.That( result.Dequeue(), Is.Null );
442+
}
443+
}
444+
445+
public class SingleValueObject
446+
{
447+
public string Value { get; set; }
448+
}
384449
}
385450
}

0 commit comments

Comments
 (0)