Handle the backslash with double quote in JsonObjectDecoder

Motivation:

The double quote may be escaped in a JSON string, but JsonObjectDecoder doesn't handle it. Resolves #5157.

Modifications:

Don't end a JSON string when processing an escaped double quote.

Result:

JsonObjectDecoder can handle backslash and double quote in a JSON string correctly.
This commit is contained in:
Xiaoyan Lin 2016-05-03 19:32:18 -07:00 committed by Norman Maurer
parent a974fff07d
commit ce1ae0eb8b
2 changed files with 61 additions and 3 deletions

View File

@ -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;
}
}
}
}

View File

@ -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());