Fix #6969: Do not reset the states while streaming Json array

Motivation:

Calling JsonObjectDecoder#reset while streaming Json array over multiple
writes causes CorruptedFrameException to be thrown.

Modifications:

While streaming Json array and if the current readerIndex has been reset,
ensure that the states will not be reset.

Result:

Fixes #6969
This commit is contained in:
Violeta Georgieva 2017-07-14 21:57:17 +03:00 committed by Norman Maurer
parent 6152990073
commit 96f52e05bf
2 changed files with 34 additions and 1 deletions

View File

@ -92,7 +92,6 @@ public class JsonObjectDecoder extends ByteToMessageDecoder {
if (this.idx > in.readerIndex() && lastReaderIndex != in.readerIndex()) {
this.idx = in.readerIndex();
reset();
}
// index of next byte to process.

View File

@ -71,6 +71,40 @@ public class JsonObjectDecoderTest {
assertFalse(ch.finish());
}
@Test
public void testStreamJsonArrayOverMultipleWrites() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder(true));
String arrayPart1 = "[{\"test";
String arrayPart2 = "case\" : \"\\\"}]Escaped dou\\\"ble quotes \\\" in JSON str\\\"ing\"";
String arrayPart3 = " }\n\n , ";
String arrayPart4 = "{\"testcase\" : \"Streaming string me";
String arrayPart5 = "ssage\"} ]";
// Test array
boolean dataAvailable = ch.writeInbound(Unpooled.copiedBuffer(" " + arrayPart1, CharsetUtil.UTF_8));
assertFalse(dataAvailable);
dataAvailable = ch.writeInbound(Unpooled.copiedBuffer(arrayPart2, CharsetUtil.UTF_8));
assertFalse(dataAvailable);
dataAvailable = ch.writeInbound(Unpooled.copiedBuffer(arrayPart3, CharsetUtil.UTF_8));
assertTrue(dataAvailable);
dataAvailable = ch.writeInbound(Unpooled.copiedBuffer(arrayPart4, CharsetUtil.UTF_8));
assertTrue(dataAvailable);
dataAvailable = ch.writeInbound(Unpooled.copiedBuffer(arrayPart5 + " ", CharsetUtil.UTF_8));
assertTrue(dataAvailable);
ByteBuf res = ch.readInbound();
assertEquals("{\"testcase\" : \"\\\"}]Escaped dou\\\"ble quotes \\\" in JSON str\\\"ing\" }",
res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals("{\"testcase\" : \"Streaming string message\"}", res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testSingleByteStream() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());