Fixes issue 2008. Corrects JSONObject's toString to properly escape
backslashes and quotes.
Issue: 2008
Patch by: fredsa, jat
Review by: scottb
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1963 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/json/client/JSONObject.java b/user/src/com/google/gwt/json/client/JSONObject.java
index b1fe522..84043e7 100644
--- a/user/src/com/google/gwt/json/client/JSONObject.java
+++ b/user/src/com/google/gwt/json/client/JSONObject.java
@@ -185,9 +185,8 @@
var subObj =
(this.@com.google.gwt.json.client.JSONObject::frontStore[key]).
@com.google.gwt.json.client.JSONValue::toString()();
- out.push("\"");
- out.push(key);
- out.push("\":");
+ out.push(@com.google.gwt.json.client.JSONString::escapeValue(Ljava/lang/String;)(key));
+ out.push(":");
out.push(subObj);
}
out.push("}")
diff --git a/user/src/com/google/gwt/json/client/JSONString.java b/user/src/com/google/gwt/json/client/JSONString.java
index fbd824e..73bce23 100644
--- a/user/src/com/google/gwt/json/client/JSONString.java
+++ b/user/src/com/google/gwt/json/client/JSONString.java
@@ -29,6 +29,13 @@
return (lookedUp == null) ? c : lookedUp;
}-*/;
+ static native String escapeValue(String toEscape) /*-{
+ var s = toEscape.replace(/[\x00-\x1F"\\]/g, function(x) {
+ return @com.google.gwt.json.client.JSONString::escapeChar(Ljava/lang/String;)(x);
+ });
+ return "\"" + s + "\"";
+ }-*/;
+
private static native JavaScriptObject initEscapeTable() /*-{
var out = [
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005",
@@ -80,11 +87,4 @@
public String toString() {
return escapeValue(value);
}
-
- private native String escapeValue(String toEscape) /*-{
- var s = toEscape.replace(/[\x00-\x1F"\\]/g, function(x) {
- return @com.google.gwt.json.client.JSONString::escapeChar(Ljava/lang/String;)(x);
- });
- return "\"" + s + "\"";
- }-*/;
}
diff --git a/user/test/com/google/gwt/json/client/JSONTest.java b/user/test/com/google/gwt/json/client/JSONTest.java
index e5a9feb..d946328 100644
--- a/user/test/com/google/gwt/json/client/JSONTest.java
+++ b/user/test/com/google/gwt/json/client/JSONTest.java
@@ -17,8 +17,10 @@
import com.google.gwt.junit.client.GWTTestCase;
+import java.util.Set;
+
/**
- * TODO: document me.
+ * Test case for JSONValue and friends.
*/
public class JSONTest extends GWTTestCase {
static final String menuTest = "{\"menu\": {\n" + " \"id\": \"file\",\n"
@@ -43,6 +45,54 @@
+ " \"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\"\n"
+ " }\n" + "}} \n" + "";
+ private static void assertJSONArrayEquals(JSONArray expected, JSONArray actual) {
+ assertEquals(expected.size(), actual.size());
+ for (int i = 0; i < expected.size(); ++i) {
+ assertJSONValueEquals(expected.get(i), actual.get(i));
+ }
+ }
+
+ private static void assertJSONObjectEquals(JSONObject expected,
+ JSONObject actual) {
+ Set<String> actKeys = actual.keySet();
+ for (String key : expected.keySet()) {
+ actKeys.remove(key);
+ assertTrue(actual.containsKey(key));
+ JSONValue expValue = expected.get(key);
+ JSONValue actValue = actual.get(key);
+ assertJSONValueEquals(expValue, actValue);
+ }
+ assertEquals(0, actKeys.size());
+ }
+
+ private static void assertJSONValueEquals(JSONValue expected, JSONValue actual) {
+ if (expected.isArray() != null) {
+ JSONArray expArray = expected.isArray();
+ JSONArray actArray = actual.isArray();
+ assertJSONArrayEquals(expArray, actArray);
+ } else if (expected.isBoolean() != null) {
+ JSONBoolean expBool = expected.isBoolean();
+ JSONBoolean actBool = actual.isBoolean();
+ assertEquals(expBool.booleanValue(), actBool.booleanValue());
+ } else if (expected.isNull() != null) {
+ assertNotNull(actual.isNull());
+ } else if (expected.isNumber() != null) {
+ JSONNumber expNum = expected.isNumber();
+ JSONNumber actNum = actual.isNumber();
+ assertEquals(expNum.getValue(), actNum.getValue());
+ } else if (expected.isObject() != null) {
+ JSONObject expObj = expected.isObject();
+ JSONObject actObj = actual.isObject();
+ assertJSONObjectEquals(expObj, actObj);
+ } else if (expected.isString() != null) {
+ JSONString expStr = expected.isString();
+ JSONString actStr = actual.isString();
+ assertEquals(expStr.stringValue(), actStr.stringValue());
+ } else {
+ fail("Unknown JSONValue " + expected);
+ }
+ }
+
/**
* Returns the module name for GWT unit test running.
*/
@@ -294,6 +344,19 @@
"hello"));
}
+ public void testRoundTripEscaping() {
+ JSONObject obj = new JSONObject();
+ obj.put("a", new JSONNumber(42));
+ obj.put("\\", new JSONNumber(43));
+ obj.put("\"", new JSONNumber(44));
+
+ String toString = obj.toString();
+ assertEquals("{\"a\":42.0, \"\\\\\":43.0, \"\\\"\":44.0}", toString.trim());
+ JSONValue parseResponse = JSONParser.parse(toString);
+ JSONObject obj2 = parseResponse.isObject();
+ assertJSONObjectEquals(obj, obj2);
+ }
+
public void testSimpleNested() {
JSONObject j1 = new JSONObject();
j1.put("test1", new JSONString(""));
@@ -332,10 +395,13 @@
JSONObject object = JSONParser.parse("{\"a\":\"b\",\"null\":\"foo\"}").isObject();
assertNotNull(object);
- assertEquals("b", object.get(stringAsPrimitive("a")).isString().stringValue());
+ assertEquals("b",
+ object.get(stringAsPrimitive("a")).isString().stringValue());
assertEquals("b", object.get(stringAsObject("a")).isString().stringValue());
- assertEquals("foo", object.get(stringAsPrimitive("null")).isString().stringValue());
- assertEquals("foo", object.get(stringAsObject("null")).isString().stringValue());
+ assertEquals("foo",
+ object.get(stringAsPrimitive("null")).isString().stringValue());
+ assertEquals("foo",
+ object.get(stringAsObject("null")).isString().stringValue());
assertNull(object.get(null));
}