Skip to content

Commit 828fd3a

Browse files
authored
CompressedXContent to honour ToXContent#isFragment (#69574)
CompressedXContent can be constructed providing a ToXContent as argument, which gets then serialized by calling its toXContent method. Depending on whether it is a whole object or a fragment, a start and end object should or should not be written. Currently, we only use CompressedXContent to serialize ToXContentFragments hence we never caught this issue, but it is something that we can easily fix before we stumble upon it.
1 parent a46977f commit 828fd3a

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

server/src/main/java/org/elasticsearch/common/compress/CompressedXContent.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,13 @@ public CompressedXContent(ToXContent xcontent, XContentType type, ToXContent.Par
6464
CRC32 crc32 = new CRC32();
6565
OutputStream checkedStream = new CheckedOutputStream(compressedStream, crc32);
6666
try (XContentBuilder builder = XContentFactory.contentBuilder(type, checkedStream)) {
67-
builder.startObject();
67+
if (xcontent.isFragment()) {
68+
builder.startObject();
69+
}
6870
xcontent.toXContent(builder, params);
69-
builder.endObject();
71+
if (xcontent.isFragment()) {
72+
builder.endObject();
73+
}
7074
}
7175
this.bytes = BytesReference.toBytes(bStream.bytes());
7276
this.crc32 = (int) crc32.getValue();

server/src/test/java/org/elasticsearch/common/compress/DeflateCompressedXContentTests.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
import org.apache.lucene.util.TestUtil;
1212
import org.elasticsearch.common.bytes.BytesReference;
1313
import org.elasticsearch.common.io.stream.BytesStreamOutput;
14+
import org.elasticsearch.common.xcontent.ToXContent;
15+
import org.elasticsearch.common.xcontent.ToXContentFragment;
16+
import org.elasticsearch.common.xcontent.ToXContentObject;
17+
import org.elasticsearch.common.xcontent.XContentType;
1418
import org.elasticsearch.test.ESTestCase;
1519
import org.junit.Assert;
1620

@@ -87,4 +91,19 @@ public void testHashCode() throws IOException {
8791
assertFalse(new CompressedXContent("{\"a\":\"b\"}").hashCode() == new CompressedXContent("{\"a\":\"c\"}").hashCode());
8892
}
8993

94+
public void testToXContentObject() throws IOException {
95+
ToXContentObject toXContentObject = (builder, params) -> {
96+
builder.startObject();
97+
builder.endObject();
98+
return builder;
99+
};
100+
CompressedXContent compressedXContent = new CompressedXContent(toXContentObject, XContentType.JSON, ToXContent.EMPTY_PARAMS);
101+
assertEquals("{}", compressedXContent.string());
102+
}
103+
104+
public void testToXContentFragment() throws IOException {
105+
ToXContentFragment toXContentFragment = (builder, params) -> builder.field("field", "value");
106+
CompressedXContent compressedXContent = new CompressedXContent(toXContentFragment, XContentType.JSON, ToXContent.EMPTY_PARAMS);
107+
assertEquals("{\"field\":\"value\"}", compressedXContent.string());
108+
}
90109
}

0 commit comments

Comments
 (0)