Skip to content

Commit 2647c3b

Browse files
author
rstam
committed
CSHARP-547: Replace use of $csharpnull with _csharpnull because the leading "$" causes secondaries to crash in server 2.2. The new representation will always be used when serializing, but both representation are supported when deserializing. This is a rare edge case and almost no one should be affected by it.
1 parent bd9a0ae commit 2647c3b

File tree

5 files changed

+24
-9
lines changed

5 files changed

+24
-9
lines changed

Bson/IO/BsonWriter.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,6 @@ protected void CheckElementName(string name)
649649
// a few element names starting with $ have to be allowed for historical reasons
650650
switch (name)
651651
{
652-
case "$csharpnull":
653652
case "$code":
654653
case "$db":
655654
case "$id":

Bson/Serialization/Serializers/BsonValueSerializers.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,18 +1311,28 @@ public override object Deserialize(
13111311
VerifyTypes(nominalType, actualType, typeof(BsonNull));
13121312

13131313
var bsonType = bsonReader.GetCurrentBsonType();
1314+
string message;
13141315
switch (bsonType)
13151316
{
13161317
case BsonType.Null:
13171318
bsonReader.ReadNull();
13181319
return BsonNull.Value;
13191320
case BsonType.Document:
13201321
bsonReader.ReadStartDocument();
1321-
var csharpNull = bsonReader.ReadBoolean("$csharpnull");
1322-
bsonReader.ReadEndDocument();
1323-
return csharpNull ? null : BsonNull.Value;
1322+
var name = bsonReader.ReadName();
1323+
if (name == "_csharpnull" || name == "$csharpnull")
1324+
{
1325+
var csharpNull = bsonReader.ReadBoolean();
1326+
bsonReader.ReadEndDocument();
1327+
return csharpNull ? null : BsonNull.Value;
1328+
}
1329+
else
1330+
{
1331+
message = string.Format("Unexpected element name while deserializing a BsonNull: {0}.", name);
1332+
throw new FileFormatException(message);
1333+
}
13241334
default:
1325-
var message = string.Format("Cannot deserialize BsonNull from BsonType {0}.", bsonType);
1335+
message = string.Format("Cannot deserialize BsonNull from BsonType {0}.", bsonType);
13261336
throw new FileFormatException(message);
13271337
}
13281338
}
@@ -1343,7 +1353,7 @@ public override void Serialize(
13431353
if (value == null)
13441354
{
13451355
bsonWriter.WriteStartDocument();
1346-
bsonWriter.WriteBoolean("$csharpnull", true);
1356+
bsonWriter.WriteBoolean("_csharpnull", true);
13471357
bsonWriter.WriteEndDocument();
13481358
}
13491359
else

BsonUnitTests/DefaultSerializer/Serializers/BsonValueSerializerTests.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1062,12 +1062,18 @@ public void TestNull()
10621062
{
10631063
var obj = new TestClass(null);
10641064
var json = obj.ToJson();
1065-
var expected = "{ 'B' : null, 'V' : # }".Replace("#", "{ '$csharpnull' : true }").Replace("'", "\"");
1065+
var expected = "{ 'B' : null, 'V' : # }".Replace("#", "{ '_csharpnull' : true }").Replace("'", "\"");
10661066
Assert.AreEqual(expected, json);
10671067

10681068
var bson = obj.ToBson();
10691069
var rehydrated = BsonSerializer.Deserialize<TestClass>(bson);
10701070
Assert.IsTrue(bson.SequenceEqual(rehydrated.ToBson()));
1071+
1072+
// test that we can still deserialize the legacy representation for a BsonNull value of C# null
1073+
var legacy = expected.Replace("_csharpnull", "$csharpnull");
1074+
rehydrated = BsonSerializer.Deserialize<TestClass>(legacy);
1075+
Assert.AreEqual(null, rehydrated.B);
1076+
Assert.AreEqual(null, rehydrated.V);
10711077
}
10721078

10731079
[Test]

DriverUnitTests/Jira/CSharp231Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ public void TestClassWithBsonNullId()
544544
_collection.RemoveAll();
545545

546546
var doc = new ClassWithBsonNullId { Id = null, X = 1 };
547-
_collection.Insert(doc); // serializes _id as { "_id" : { "$csharpnull" : true }, "X" : 1 }
547+
_collection.Insert(doc); // serializes _id as { "_id" : { "_csharpnull" : true }, "X" : 1 }
548548
Assert.AreEqual(null, doc.Id);
549549

550550
doc = new ClassWithBsonNullId { Id = BsonNull.Value, X = 1 };

DriverUnitTests/Jira/CSharp253Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public void TestLegacyDollar()
8181
var document = new BsonDocument
8282
{
8383
{ "_id", ObjectId.GenerateNewId() },
84-
{ "BsonNull", new BsonDocument("$csharpnull", true) },
84+
{ "BsonNull", new BsonDocument("_csharpnull", true) },
8585
{ "Code", new BsonDocument
8686
{
8787
{ "$code", "code" },

0 commit comments

Comments
 (0)