You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by rw...@apache.org on 2015/04/23 01:26:15 UTC

svn commit: r1675517 - in /pivot/trunk/core: src/org/apache/pivot/json/JSONSerializer.java test/org/apache/pivot/json/test/JSONSerializerTest.java test/org/apache/pivot/json/test/map.json

Author: rwhitcomb
Date: Wed Apr 22 23:26:15 2015
New Revision: 1675517

URL: http://svn.apache.org/r1675517
Log:
PIVOT-967: Fix the JSONSerializer to correctly deal with special characters
inside string values (especially \r and others).

Add the ability to directly support java.util.Map values in an object
passed to JSONSerializer.writeObject (by instantiating a MapAdapter around
the java.util.Map object).

Update the JSONSerializerTest to test these changes (both read and write).
Update the "map.json" with test values.

Modified:
    pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java
    pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java
    pivot/trunk/core/test/org/apache/pivot/json/test/map.json

Modified: pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java?rev=1675517&r1=1675516&r2=1675517&view=diff
==============================================================================
--- pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java (original)
+++ pivot/trunk/core/src/org/apache/pivot/json/JSONSerializer.java Wed Apr 22 23:26:15 2015
@@ -40,6 +40,7 @@ import org.apache.pivot.collections.Hash
 import org.apache.pivot.collections.List;
 import org.apache.pivot.collections.Map;
 import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.collections.adapter.MapAdapter;
 import org.apache.pivot.io.EchoReader;
 import org.apache.pivot.io.EchoWriter;
 import org.apache.pivot.serialization.MacroReader;
@@ -378,6 +379,8 @@ public class JSONSerializer implements S
         c = reader.read();
 
         while (c != -1 && c != t) {
+            // The JSON spec says that control characters are not supported,
+            // so silently ignore them
             if (!Character.isISOControl(c)) {
                 if (c == '\\') {
                     c = reader.read();
@@ -875,6 +878,21 @@ public class JSONSerializer implements S
                         break;
                     }
 
+                    case '\r': {
+                        stringBuilder.append("\\r");
+                        break;
+                    }
+
+                    case '\f': {
+                        stringBuilder.append("\\f");
+                        break;
+                    }
+
+                    case '\b': {
+                        stringBuilder.append("\\b");
+                        break;
+                    }
+
                     case '\\':
                     case '\"':
                     case '\'': {
@@ -883,7 +901,10 @@ public class JSONSerializer implements S
                     }
 
                     default: {
-                        if (charset.name().startsWith("UTF") || ci <= 0xFF) {
+                        // For Unicode character sets if it is a control character, then use \\uXXXX notation
+                        // and for other character sets if the value is an ASCII control character.
+                        if ((charset.name().startsWith("UTF") && !Character.isISOControl(ci)) ||
+                            (ci > 0x1F && ci != 0x7F && ci <= 0xFF)) {
                             stringBuilder.append(ci);
                         } else {
                             stringBuilder.append("\\u");
@@ -932,6 +953,8 @@ public class JSONSerializer implements S
             Map<String, Object> map;
             if (object instanceof Map<?, ?>) {
                 map = (Map<String, Object>) object;
+            } else if (object instanceof java.util.Map<?, ?>) {
+                map = new MapAdapter<>((java.util.Map<String, Object>)object);
             } else {
                 map = new BeanAdapter(object, true);
             }

Modified: pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java
URL: http://svn.apache.org/viewvc/pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java?rev=1675517&r1=1675516&r2=1675517&view=diff
==============================================================================
--- pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java (original)
+++ pivot/trunk/core/test/org/apache/pivot/json/test/JSONSerializerTest.java Wed Apr 22 23:26:15 2015
@@ -139,6 +139,7 @@ public class JSONSerializerTest {
         assertEquals(JSON.get(o1, "e.g"), 5);
         assertEquals(JSON.get(o1, "i.a"), 200);
         assertEquals(JSON.get(o1, "i.c"), true);
+        assertEquals(JSON.get(o1, "m"), "Hello\r\n\tWorld!");
 
         jsonSerializer.getJSONSerializerListeners().remove(jsonSerializerListener);
         Object o2 = jsonSerializer.readObject(getClass().getResourceAsStream("map.json"));
@@ -147,6 +148,7 @@ public class JSONSerializerTest {
         assertEquals(JSON.get(o2, "k[2].b"), 200);
         assertEquals(JSON.get(o2, "k[2].c"), "300");
         assertEquals(JSON.get(o2, "j"), 200);
+        assertEquals(JSON.get(o2, "n"), "This is a \"test\" of the 'quoting' in \\JSON\\");
 
         assertTrue(o1.equals(o2));
 
@@ -157,18 +159,25 @@ public class JSONSerializerTest {
     }
 
     @Test
-    public void testJavaMap() {
+    public void testJavaMap() throws SerializationException {
         System.out.println("Test interaction with Standard java.util.Map");
 
         java.util.HashMap<String, java.util.Map<String, String>> root = new java.util.HashMap<>();
         java.util.HashMap<String, String> child = new java.util.HashMap<>();
 
         child.put("name", "John Doe");
+        child.put("address", "123 Main St.\r\nAnytown USA");
         root.put("child", child);
 
         String childName = JSON.get(root, "child.name");
-        System.out.println("JSON child.name = \"" + childName + "\"");
+        String childAddr = JSON.get(root, "child.address");
+        System.out.println("JSON child.name = \"" + childName + "\", child.address = \"" + childAddr + "\"");
         assertEquals(childName, "John Doe");
+        assertEquals(childAddr, "123 Main St.\r\nAnytown USA");
+
+        String serializedForm = JSONSerializer.toString(root);
+        System.out.println("Serialized form: \"" + serializedForm + "\"");
+        assertEquals(serializedForm, "{child: {address: \"123 Main St.\\r\\nAnytown USA\", name: \"John Doe\"}}");
     }
 
 }

Modified: pivot/trunk/core/test/org/apache/pivot/json/test/map.json
URL: http://svn.apache.org/viewvc/pivot/trunk/core/test/org/apache/pivot/json/test/map.json?rev=1675517&r1=1675516&r2=1675517&view=diff
==============================================================================
--- pivot/trunk/core/test/org/apache/pivot/json/test/map.json (original)
+++ pivot/trunk/core/test/org/apache/pivot/json/test/map.json Wed Apr 22 23:26:15 2015
@@ -29,11 +29,13 @@
 {   ${A_B_C},
     d: ["1", "2", "${THREE}"],
     e: {f: 4, g: 5, h: 6},
-    "i": { a: ${TWO_HUNDRED}, b: "Goodbye", c: true},
+    "i": { a: ${TWO_HUNDRED}, b: "Goodbye", c: true },
     j: ${TWO_HUNDRED},
     k:  [
         {a:1, b:2, c:"${THREE}"},
         {a:1${ZERO}, b:${TWENTY}, c:"${THIRTY}"},
         {a:1${ZERO}${ZERO}, b:${TWO_HUNDRED}, c:"${THREE_HUNDRED}"}
-    ]
+    ],
+    m: "Hello\r\n\tWorld!",
+    n: "This is a \"test\" of the \'quoting\' in \\JSON\\"
 }