Skip to content

Commit 2461aab

Browse files
authored
Fix id reporting bug with _ids containing arrays (#823)
JAVA-4403
1 parent 877b6d6 commit 2461aab

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

driver-core/src/main/com/mongodb/internal/connection/IdHoldingBsonWriter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class IdHoldingBsonWriter extends LevelCountingBsonWriter {
5555
private BasicOutputBuffer outputBuffer;
5656
private String currentFieldName;
5757
private BsonValue id;
58+
private boolean idFieldIsAnArray = false;
5859

5960
public IdHoldingBsonWriter(final BsonWriter bsonWriter) {
6061
super(bsonWriter);
@@ -105,6 +106,7 @@ public void writeEndDocument() {
105106
public void writeStartArray() {
106107
if (isWritingId()) {
107108
if (getIdBsonWriter().getCurrentLevel() == -1) {
109+
idFieldIsAnArray = true;
108110
getIdBsonWriter().writeStartDocument();
109111
getIdBsonWriter().writeName(ID_FIELD_NAME);
110112
}
@@ -129,7 +131,7 @@ public void writeStartArray(final String name) {
129131
public void writeEndArray() {
130132
if (isWritingId()) {
131133
getIdBsonWriter().writeEndArray();
132-
if (getIdBsonWriter().getCurrentLevel() == 0) {
134+
if (getIdBsonWriter().getCurrentLevel() == 0 && idFieldIsAnArray) {
133135
getIdBsonWriter().writeEndDocument();
134136
id = new RawBsonDocument(getBytes()).get(ID_FIELD_NAME);
135137
}

driver-core/src/test/unit/com/mongodb/internal/connection/IdHoldingBsonWriterSpecification.groovy

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,33 @@ class IdHoldingBsonWriterSpecification extends Specification {
8888
encodedDocument == document
8989
}
9090

91+
def 'serialize _id documents containing arrays'() {
92+
def bsonBinaryWriter = new BsonBinaryWriter(new BasicOutputBuffer())
93+
def idTrackingBsonWriter = new IdHoldingBsonWriter(bsonBinaryWriter)
94+
BsonDocument document = BsonDocument.parse(json)
95+
96+
when:
97+
new BsonDocumentCodec().encode(idTrackingBsonWriter, document, EncoderContext.builder()
98+
.isEncodingCollectibleDocument(true).build())
99+
def encodedDocument = getEncodedDocument(bsonBinaryWriter.getBsonOutput())
100+
101+
then:
102+
encodedDocument == document
103+
104+
where:
105+
json << ['{"_id": {"a": []}, "b": 123}',
106+
'{"_id": {"a": [1, 2]}, "b": 123}',
107+
'{"_id": {"a": [[[[1]]]]}, "b": 123}',
108+
'{"_id": {"a": [{"a": [1, 2]}]}, "b": 123}',
109+
'{"_id": {"a": {"a": [1, 2]}}, "b": 123}',
110+
'{"_id": {"a": [1, 2], "b": [123]}}',
111+
'{"_id": [], "b": 123}',
112+
'{"_id": [1, 2], "b": 123}',
113+
'{"_id": [[1], [[2]]], "b": 123}',
114+
'{"_id": [{"a": 1}], "b": 123}',
115+
'{"_id": [{"a": [{"b": 123}]}]}']
116+
}
117+
91118
private static BsonDocument getEncodedDocument(BsonOutput buffer) {
92119
new BsonDocumentCodec().decode(new BsonBinaryReader(buffer.getByteBuffers().get(0).asNIO()),
93120
DecoderContext.builder().build())

0 commit comments

Comments
 (0)