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 b791e41037..a34334b6c0 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 @@ -190,9 +190,22 @@ public class JsonObjectDecoder extends ByteToMessageDecoder { // also contain braces/brackets and that could lead to incorrect results. if (!insideString) { insideString = true; - // If the double quote wasn't escaped then this is the end of a string. - } else if (in.getByte(idx - 1) != '\\') { - insideString = false; + } else { + int backslashCount = 0; + idx--; + while (idx >= 0) { + if (in.getByte(idx) == '\\') { + backslashCount++; + idx--; + } else { + break; + } + } + // The double quote isn't escaped only if there are even "\"s. + if (backslashCount % 2 == 0) { + // Since the double quote isn't escaped then this is the end of a string. + insideString = false; + } } } } 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 08ece60917..083b4eb1d4 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 @@ -87,6 +87,51 @@ public class JsonObjectDecoderTest { assertFalse(ch.finish()); } + @Test + public void testBackslashInString1() { + EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder()); + // {"foo" : "bar\""} + String json = "{\"foo\" : \"bar\\\"\"}"; + System.out.println(json); + ch.writeInbound(Unpooled.copiedBuffer(json, CharsetUtil.UTF_8)); + + ByteBuf res = ch.readInbound(); + assertEquals(json, res.toString(CharsetUtil.UTF_8)); + res.release(); + + assertFalse(ch.finish()); + } + + @Test + public void testBackslashInString2() { + EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder()); + // {"foo" : "bar\\"} + String json = "{\"foo\" : \"bar\\\\\"}"; + System.out.println(json); + ch.writeInbound(Unpooled.copiedBuffer(json, CharsetUtil.UTF_8)); + + ByteBuf res = ch.readInbound(); + assertEquals(json, res.toString(CharsetUtil.UTF_8)); + res.release(); + + assertFalse(ch.finish()); + } + + @Test + public void testBackslashInString3() { + EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder()); + // {"foo" : "bar\\\""} + String json = "{\"foo\" : \"bar\\\\\\\"\"}"; + System.out.println(json); + ch.writeInbound(Unpooled.copiedBuffer(json, CharsetUtil.UTF_8)); + + ByteBuf res = ch.readInbound(); + assertEquals(json, res.toString(CharsetUtil.UTF_8)); + res.release(); + + assertFalse(ch.finish()); + } + @Test public void testMultipleJsonObjectsInOneWrite() { EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());