Skip to content

Commit 08fe6b0

Browse files
authored
CSHARP-6043: NullReferenceException in IEnumerableSerializerBase.Serialize when projecting nullable array with conditional Select (#2012)
1 parent d06d0e4 commit 08fe6b0

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

src/MongoDB.Driver/Linq/Linq3Implementation/Serializers/IEnumerableSerializerBase.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
using System.Collections.Generic;
17+
using MongoDB.Bson;
1718
using MongoDB.Bson.Serialization;
1819
using MongoDB.Bson.Serialization.Serializers;
1920
using MongoDB.Driver.Core.Misc;
@@ -36,6 +37,11 @@ public IEnumerableSerializerBase(IBsonSerializer<TItem> itemSerializer)
3637
public override TEnumerable Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
3738
{
3839
var reader = context.Reader;
40+
if (reader.GetCurrentBsonType() == BsonType.Null)
41+
{
42+
reader.ReadNull();
43+
return default;
44+
}
3945
reader.ReadStartArray();
4046
var items = new List<TItem>();
4147
while (reader.ReadBsonType() != 0)
@@ -64,6 +70,11 @@ obj is IEnumerableSerializerBase<TEnumerable, TItem> other &&
6470
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TEnumerable value)
6571
{
6672
var writer = context.Writer;
73+
if (value == null)
74+
{
75+
writer.WriteNull();
76+
return;
77+
}
6778
writer.WriteStartArray();
6879
foreach (var item in value)
6980
{

tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Serializers/IEnumerableSerializerBaseTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Collections.Generic;
1717
using FluentAssertions;
1818
using MongoDB.Bson;
19+
using MongoDB.Bson.IO;
1920
using MongoDB.Bson.Serialization;
2021
using MongoDB.Bson.Serialization.Serializers;
2122
using MongoDB.Driver.Linq.Linq3Implementation.Serializers;
@@ -101,6 +102,37 @@ public void GetHashCode_should_return_zero()
101102
result.Should().Be(0);
102103
}
103104

105+
[Fact]
106+
public void Serialize_null_should_write_null()
107+
{
108+
var serializer = new ConcreteIEnumerableSerializerBase<IEnumerable<int>, int>(Int32Serializer.Instance);
109+
var document = new BsonDocument();
110+
using var writer = new BsonDocumentWriter(document);
111+
var context = BsonSerializationContext.CreateRoot(writer);
112+
writer.WriteStartDocument();
113+
writer.WriteName("x");
114+
115+
serializer.Serialize(context, new BsonSerializationArgs(), null);
116+
117+
writer.WriteEndDocument();
118+
document["x"].Should().Be(BsonNull.Value);
119+
}
120+
121+
[Fact]
122+
public void Deserialize_null_should_return_default()
123+
{
124+
var serializer = new ConcreteIEnumerableSerializerBase<IEnumerable<int>, int>(Int32Serializer.Instance);
125+
var document = new BsonDocument("x", BsonNull.Value);
126+
using var reader = new BsonDocumentReader(document);
127+
reader.ReadStartDocument();
128+
reader.ReadName("x");
129+
var context = BsonDeserializationContext.CreateRoot(reader);
130+
131+
var result = serializer.Deserialize(context, new BsonDeserializationArgs { NominalType = typeof(IEnumerable<int>) });
132+
133+
result.Should().BeNull();
134+
}
135+
104136
internal class ConcreteIEnumerableSerializerBase<TEnumerable, TItem> : IEnumerableSerializerBase<TEnumerable, TItem>
105137
where TEnumerable : IEnumerable<TItem>
106138
{

0 commit comments

Comments
 (0)