From 96f52e05bf9f9cbf210bfe97007ddcd690e394ce Mon Sep 17 00:00:00 2001 From: Violeta Georgieva Date: Fri, 14 Jul 2017 21:57:17 +0300 Subject: [PATCH] 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 --- .../handler/codec/json/JsonObjectDecoder.java | 1 - .../codec/json/JsonObjectDecoderTest.java | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/codec/src/main/java/io/netty/handler/codec/json/JsonObjectDecoder.java b/codec/src/main/java/io/netty/handler/codec/json/JsonObjectDecoder.java index cd5db99ff7..037c60c0af 100644 --- a/codec/src/main/java/io/netty/handler/codec/json/JsonObjectDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/json/JsonObjectDecoder.java @@ -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. diff --git a/codec/src/test/java/io/netty/handler/codec/json/JsonObjectDecoderTest.java b/codec/src/test/java/io/netty/handler/codec/json/JsonObjectDecoderTest.java index e1f28a5794..29175db3c7 100644 --- a/codec/src/test/java/io/netty/handler/codec/json/JsonObjectDecoderTest.java +++ b/codec/src/test/java/io/netty/handler/codec/json/JsonObjectDecoderTest.java @@ -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());