From d602f822d50bec166cd34c8ece170b13694268a9 Mon Sep 17 00:00:00 2001 From: Mark Slee Date: Wed, 28 Nov 2007 02:45:13 +0000 Subject: [PATCH] Complete the proper handling of all special characters in JSON strings for TJSONProtocol Reviewed By: dreiss Test Plan: test/java/TestClient git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665373 13f79535-47bb-0310-9956-ffa450edef68 --- lib/java/src/TByteArrayOutputStream.java | 29 ++++++++++++ lib/java/src/protocol/TJSONProtocol.java | 47 ++++++++++++++++---- lib/java/src/transport/TFramedTransport.java | 30 +++---------- 3 files changed, 75 insertions(+), 31 deletions(-) create mode 100644 lib/java/src/TByteArrayOutputStream.java diff --git a/lib/java/src/TByteArrayOutputStream.java b/lib/java/src/TByteArrayOutputStream.java new file mode 100644 index 00000000..94ce0036 --- /dev/null +++ b/lib/java/src/TByteArrayOutputStream.java @@ -0,0 +1,29 @@ +// Copyright (c) 2006- Facebook +// Distributed under the Thrift Software License +// +// See accompanying file LICENSE or visit the Thrift site at: +// http://developers.facebook.com/thrift/ + +package com.facebook.thrift; + +import java.io.ByteArrayOutputStream; + +/** + * Class that allows access to the underlying buf without doing deep + * copies on it. + * + * @author Mark Slee + */ +public class TByteArrayOutputStream extends ByteArrayOutputStream { + public TByteArrayOutputStream(int size) { + super(size); + } + + public byte[] get() { + return buf; + } + + public int len() { + return count; + } +} diff --git a/lib/java/src/protocol/TJSONProtocol.java b/lib/java/src/protocol/TJSONProtocol.java index 07dee63e..fefa65c3 100644 --- a/lib/java/src/protocol/TJSONProtocol.java +++ b/lib/java/src/protocol/TJSONProtocol.java @@ -6,8 +6,10 @@ package com.facebook.thrift.protocol; +import com.facebook.thrift.TByteArrayOutputStream; import com.facebook.thrift.TException; import com.facebook.thrift.transport.TTransport; +import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.util.Stack; @@ -30,11 +32,11 @@ public class TJSONProtocol extends TProtocol { public static final byte[] COMMA = new byte[] {','}; public static final byte[] COLON = new byte[] {':'}; - public static final byte[] QUOTE = new byte[] {'"'}; public static final byte[] LBRACE = new byte[] {'{'}; public static final byte[] RBRACE = new byte[] {'}'}; public static final byte[] LBRACKET = new byte[] {'['}; public static final byte[] RBRACKET = new byte[] {']'}; + public static final char QUOTE = '"'; protected class Context { protected void write() throws TException {} @@ -208,26 +210,55 @@ public class TJSONProtocol extends TProtocol { public void writeString(String str) throws TException { writeContext_.write(); - trans_.write(QUOTE); - int length = str.length(); - StringBuffer escape = new StringBuffer(length); - char c; + StringBuffer escape = new StringBuffer(length + 16); + escape.append(QUOTE); for (int i = 0; i < length; ++i) { - c = str.charAt(i); + char c = str.charAt(i); switch (c) { case '"': case '\\': escape.append('\\'); escape.append(c); break; + case '\b': + escape.append('\\'); + escape.append('b'); + break; + case '\f': + escape.append('\\'); + escape.append('f'); + break; + case '\n': + escape.append('\\'); + escape.append('n'); + break; + case '\r': + escape.append('\\'); + escape.append('r'); + break; + case '\t': + escape.append('\\'); + escape.append('t'); + break; default: - escape.append(c); + // Control characeters! According to JSON RFC u0020 (space) + if (c < ' ') { + String hex = Integer.toHexString(c); + escape.append('\\'); + escape.append('u'); + for (int j = 4; j > hex.length(); --j) { + escape.append('0'); + } + escape.append(hex); + } else { + escape.append(c); + } break; } } + escape.append(QUOTE); _writeStringData(escape.toString()); - trans_.write(QUOTE); } public void writeBinary(byte[] bin) throws TException { diff --git a/lib/java/src/transport/TFramedTransport.java b/lib/java/src/transport/TFramedTransport.java index 9eb068d5..7121c09c 100644 --- a/lib/java/src/transport/TFramedTransport.java +++ b/lib/java/src/transport/TFramedTransport.java @@ -9,6 +9,8 @@ package com.facebook.thrift.transport; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import com.facebook.thrift.TByteArrayOutputStream; + /** * Socket implementation of the TTransport interface. To be commented soon! * @@ -21,30 +23,12 @@ public class TFramedTransport extends TTransport { */ private TTransport transport_ = null; - /** - * Class that allows access to the underlying buf without doing deep - * copies on it. - */ - private static class MyByteArrayOutputStream extends ByteArrayOutputStream { - public MyByteArrayOutputStream(int size) { - super(size); - } - - public byte[] get() { - return buf; - } - - public int len() { - return count; - } - } - /** * Buffer for output */ - private final MyByteArrayOutputStream writeBuffer_ = - new MyByteArrayOutputStream(1024); - + private final TByteArrayOutputStream writeBuffer_ = + new TByteArrayOutputStream(1024); + /** * Buffer for input */ @@ -59,7 +43,7 @@ public class TFramedTransport extends TTransport { * Whether to frame output */ private boolean frameWrite_ = true; - + /** * Constructor wraps around another tranpsort */ @@ -135,7 +119,7 @@ public class TFramedTransport extends TTransport { } writeBuffer_.write(buf, off, len); } - + public void flush() throws TTransportException { if (!frameWrite_) { transport_.flush(); -- 2.17.1