Skip to content

Commit 7e73aff

Browse files
committed
Fix some collection built in serializer bypass null check. #211
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 1edc982 commit 7e73aff

File tree

6 files changed

+87
-17
lines changed

6 files changed

+87
-17
lines changed

CHANGES.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,3 +594,8 @@ Release 0.8.0 beta 2016/07/24
594594
IMPROVEMENTS
595595
* Relax constructor based deserialization condition. It will be used even if there are any settable members(including private property setters). Part of issue #178 and fixes issue #135.
596596
* PackHelpers and UnpackHelpers APIs are now backward compatible.
597+
598+
Release 0.8.1 2017/02/02
599+
600+
BUG FIXES
601+
* Fix null items of complex type in List<T> or Dictionary<TKey, TValue> will not be deserialized as null. Issue #211.

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
@@ -354,5 +354,70 @@ public void SetItems( List<int> items )
354354
}
355355
}
356356
#endif // !SILVERLIGHT && !AOT && !NETSTANDARD1_1 && !NETSTANDARD1_3
357+
358+
[Test]
359+
public void TestIssue211_ListOfT()
360+
{
361+
var target = new SerializationContext().GetSerializer<List<SingleValueObject>>();
362+
using ( var buffer = new MemoryStream() )
363+
{
364+
target.Pack( buffer, new List<SingleValueObject> { null } );
365+
buffer.Position = 0;
366+
var result = target.Unpack( buffer );
367+
Assert.That( result.Count, Is.EqualTo( 1 ) );
368+
Assert.That( result[ 0 ], Is.Null );
369+
}
370+
}
371+
372+
[Test]
373+
public void TestIssue211_DictionaryOfT()
374+
{
375+
var target = new SerializationContext().GetSerializer<Dictionary<string, SingleValueObject>>();
376+
using ( var buffer = new MemoryStream() )
377+
{
378+
target.Pack( buffer, new Dictionary<string, SingleValueObject> { { String.Empty, null } } );
379+
buffer.Position = 0;
380+
var result = target.Unpack( buffer );
381+
Assert.That( result.Count, Is.EqualTo( 1 ) );
382+
Assert.That( result.First().Value, Is.Null );
383+
}
384+
}
385+
386+
[Test]
387+
public void TestIssue211_StackOfT()
388+
{
389+
var target = new SerializationContext().GetSerializer<Stack<SingleValueObject>>();
390+
using ( var buffer = new MemoryStream() )
391+
{
392+
var obj = new Stack<SingleValueObject>();
393+
obj.Push( null );
394+
target.Pack( buffer, obj );
395+
buffer.Position = 0;
396+
var result = target.Unpack( buffer );
397+
Assert.That( result.Count, Is.EqualTo( 1 ) );
398+
Assert.That( result.Pop(), Is.Null );
399+
}
400+
}
401+
402+
[Test]
403+
public void TestIssue211_QueueOfT()
404+
{
405+
var target = new SerializationContext().GetSerializer<Queue<SingleValueObject>>();
406+
using ( var buffer = new MemoryStream() )
407+
{
408+
var obj = new Queue<SingleValueObject>();
409+
obj.Enqueue( null );
410+
target.Pack( buffer, obj );
411+
buffer.Position = 0;
412+
var result = target.Unpack( buffer );
413+
Assert.That( result.Count, Is.EqualTo( 1 ) );
414+
Assert.That( result.Dequeue(), Is.Null );
415+
}
416+
}
417+
418+
public class SingleValueObject
419+
{
420+
public string Value { get; set; }
421+
}
357422
}
358423
}

0 commit comments

Comments
 (0)