Properly encode JSON strings
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 9 Apr 2010 12:05:02 +0000 (14:05 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 9 Apr 2010 12:05:02 +0000 (14:05 +0200)
src/json.c
test/test_json.c

index 1cef6bd..b844b51 100644 (file)
@@ -134,7 +134,7 @@ static int json_one_char(const char **p, char *out)
         case 'b':
             *out = '\b'; break;
         case 'f':
-            *out = '\b'; break;
+            *out = '\f'; break;
         case 'n':
             *out = '\n'; break;
         case 'r':
@@ -460,6 +460,46 @@ struct json_node *json_parse(const char *json_str, const char **errmsg)
     return json_parse2(json_str, errmsg, 0);
 }
 
+static void wrbuf_json_write(WRBUF b, const char *cp, size_t sz)
+{
+    size_t i;
+    for (i = 0; i < sz; i++)
+    {
+        if (cp[i] > 0 && cp[i] < 32)
+        {
+            wrbuf_putc(b, '\\');
+            switch (cp[i])
+            {
+            case '\b': wrbuf_putc(b, 'b'); break;
+            case '\f': wrbuf_putc(b, 'f'); break;
+            case '\n': wrbuf_putc(b, 'n'); break;
+            case '\r': wrbuf_putc(b, 'r'); break;
+            case '\t': wrbuf_putc(b, 't'); break;
+            default:
+                wrbuf_printf(b, "u%04x", cp[i]);
+            }
+        }
+        else if (cp[i] == '"')
+        {
+            wrbuf_putc(b, '\\'); wrbuf_putc(b, '"');
+        }
+        else if (cp[i] == '\\')
+        {
+            wrbuf_putc(b, '\\'); wrbuf_putc(b, '\\');
+        }
+        else
+        {   /* leave encoding as raw UTF-8 */
+            wrbuf_putc(b, cp[i]);
+        }
+    }       
+        
+}
+
+void wrbuf_json_puts(WRBUF b, const char *str)
+{
+    return wrbuf_json_write(b, str, strlen(str));
+}
+
 void json_write_wrbuf(struct json_node *node, WRBUF result)
 {
     switch (node->type)
@@ -491,7 +531,7 @@ void json_write_wrbuf(struct json_node *node, WRBUF result)
         break;
     case json_node_string:
         wrbuf_puts(result, "\"");
-        wrbuf_puts(result, node->u.string);
+        wrbuf_json_puts(result, node->u.string);
         wrbuf_puts(result, "\"");
         break;
     case json_node_number:
index eace27e..d402c0e 100644 (file)
@@ -110,9 +110,24 @@ static void tst1(void)
 
     YAZ_CHECK(expect(p, "{\"a\":[1,2,3]}", "{\"a\":[1,2,3]}"));
 
-    YAZ_CHECK(expect(p, "{\"k\":\"\\t\"}", "{\"k\":\"\x09\"}"));
+    YAZ_CHECK(expect(p, "{\"k\":\"\\t\"}", "{\"k\":\"\\t\"}"));
+    YAZ_CHECK(expect(p, "{\"k\":\"\t\"}", "{\"k\":\"\\t\"}"));
 
-    YAZ_CHECK(expect(p, "{\"k\":\"\\u0009\"}", "{\"k\":\"\x09\"}"));
+    YAZ_CHECK(expect(p, "{\"k\":\"\\n\"}", "{\"k\":\"\\n\"}"));
+    YAZ_CHECK(expect(p, "{\"k\":\"\n\"}", "{\"k\":\"\\n\"}"));
+
+    YAZ_CHECK(expect(p, "{\"k\":\"\\r\"}", "{\"k\":\"\\r\"}"));
+    YAZ_CHECK(expect(p, "{\"k\":\"\r\"}", "{\"k\":\"\\r\"}"));
+
+    YAZ_CHECK(expect(p, "{\"k\":\"\\f\"}", "{\"k\":\"\\f\"}"));
+    YAZ_CHECK(expect(p, "{\"k\":\"\f\"}", "{\"k\":\"\\f\"}"));
+
+    YAZ_CHECK(expect(p, "{\"k\":\"\\b\"}", "{\"k\":\"\\b\"}"));
+    YAZ_CHECK(expect(p, "{\"k\":\"\b\"}", "{\"k\":\"\\b\"}"));
+
+    YAZ_CHECK(expect(p,
+                     "{\"k\":\"\\u0001\\u0002\"}",
+                     "{\"k\":\"\\u0001\\u0002\"}"));
 
     json_parser_destroy(p);
 }