Skip to content

Commit 6042afc

Browse files
authored
CSHARP-4756: MongoDB.Bson.BsonSerializationException (when serializing List of MongoDBRef) (#1167)
1 parent 20a74b5 commit 6042afc

File tree

2 files changed

+62
-25
lines changed

2 files changed

+62
-25
lines changed

src/MongoDB.Bson/IO/BsonWriter.cs

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -203,19 +203,13 @@ public void PushSettings(Action<BsonWriterSettings> configurator)
203203
/// Writes the end of a BSON array to the writer.
204204
/// </summary>
205205
public virtual void WriteEndArray()
206-
{
207-
_serializationDepth--;
208-
}
206+
=> ExitSerializationScope();
209207

210208
/// <summary>
211209
/// Writes the end of a BSON document to the writer.
212210
/// </summary>
213211
public virtual void WriteEndDocument()
214-
{
215-
_serializationDepth--;
216-
217-
PopElementNameValidator();
218-
}
212+
=> ExitSerializationScope();
219213

220214
/// <summary>
221215
/// Writes a BSON Int32 to the writer.
@@ -362,28 +356,13 @@ public virtual void WriteRawBsonDocument(IByteBuffer slice)
362356
/// Writes the start of a BSON array to the writer.
363357
/// </summary>
364358
public virtual void WriteStartArray()
365-
{
366-
_serializationDepth++;
367-
if (_serializationDepth > _settings.MaxSerializationDepth)
368-
{
369-
throw new BsonSerializationException("Maximum serialization depth exceeded (does the object being serialized have a circular reference?).");
370-
}
371-
}
359+
=> EnterSerializationScope();
372360

373361
/// <summary>
374362
/// Writes the start of a BSON document to the writer.
375363
/// </summary>
376364
public virtual void WriteStartDocument()
377-
{
378-
_serializationDepth++;
379-
if (_serializationDepth > _settings.MaxSerializationDepth)
380-
{
381-
throw new BsonSerializationException("Maximum serialization depth exceeded (does the object being serialized have a circular reference?).");
382-
}
383-
384-
var childValidator = _useChildValidator ? _elementNameValidator.GetValidatorForChildContent(_name) : _elementNameValidator;
385-
PushElementNameValidator(childValidator);
386-
}
365+
=> EnterSerializationScope();
387366

388367
/// <summary>
389368
/// Writes a BSON String to the writer.
@@ -470,5 +449,23 @@ protected void ThrowInvalidState(string methodName, params BsonWriterState[] val
470449
methodName, validStatesString, _state);
471450
throw new InvalidOperationException(message);
472451
}
452+
453+
private void EnterSerializationScope()
454+
{
455+
_serializationDepth++;
456+
if (_serializationDepth > _settings.MaxSerializationDepth)
457+
{
458+
throw new BsonSerializationException("Maximum serialization depth exceeded (does the object being serialized have a circular reference?).");
459+
}
460+
461+
var childValidator = _useChildValidator ? _elementNameValidator.GetValidatorForChildContent(_name) : _elementNameValidator;
462+
PushElementNameValidator(childValidator);
463+
}
464+
465+
private void ExitSerializationScope()
466+
{
467+
_serializationDepth--;
468+
PopElementNameValidator();
469+
}
473470
}
474471
}

tests/MongoDB.Bson.Tests/IO/BsonWriterTests.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,46 @@ public void BsonWriter_should_validate_child_elements_names(
166166
}
167167
}
168168

169+
[Theory]
170+
[InlineData(0)]
171+
[InlineData(1)]
172+
[InlineData(2)]
173+
[InlineData(10)]
174+
public void BsonWriter_array_should_use_own_element_validator(int arraySize)
175+
{
176+
var arrayItemValidator = CreatePrefixValidatorMock("$");
177+
var rootValidator = CreatePrefixValidatorMock("#", arrayItemValidator.Object);
178+
179+
using (var stream = new MemoryStream())
180+
using (var writer = new BsonBinaryWriter(stream))
181+
{
182+
writer.WriteStartDocument();
183+
writer.PushElementNameValidator(rootValidator.Object);
184+
185+
writer.WriteName("#array");
186+
writer.WriteStartArray();
187+
188+
for (var i = 0; i < arraySize; i++)
189+
{
190+
writer.WriteStartDocument();
191+
192+
writer.WriteName("$a");
193+
writer.WriteInt32(i);
194+
195+
writer.WriteEndDocument();
196+
}
197+
198+
writer.WriteEndArray();
199+
200+
writer.WriteName("#value");
201+
writer.WriteInt32(arraySize);
202+
writer.WriteEndDocument();
203+
}
204+
205+
rootValidator.Verify(v => v.IsValidElementName(It.IsAny<string>()), Times.Exactly(2));
206+
arrayItemValidator.Verify(v => v.IsValidElementName(It.IsAny<string>()), Times.Exactly(arraySize));
207+
}
208+
169209
// private methods
170210
private Mock<IElementNameValidator>[] CreatePrefixValidatorsNestedMock(string[] prefixes)
171211
{

0 commit comments

Comments
 (0)