Browse Source

[1626] fix non-printable escaping in json conv

Jelte Jansen 13 years ago
parent
commit
737c4eb744
2 changed files with 58 additions and 13 deletions
  1. 53 8
      src/lib/cc/data.cc
  2. 5 5
      src/lib/cc/tests/data_unittests.cc

+ 53 - 8
src/lib/cc/data.cc

@@ -318,13 +318,37 @@ str_from_stringstream(std::istream &in, const std::string& file, const int line,
     while (c != EOF && c != '"') {
         if (c == '\\') {
             // see the spec for allowed escape characters
-            if (strchr("\"\\/\b\f\n\r\t", in.peek()) != NULL) {
-                // drop the escape
-                c = in.get();
-                ++pos;
-            } else {
+            switch (in.peek()) {
+            case '"':
+                c = '"';
+                break;
+            case '/':
+                c = '/';
+                break;
+            case '\\':
+                c = '\\';
+                break;
+            case 'b':
+                c = '\b';
+                break;
+            case 'f':
+                c = '\f';
+                break;
+            case 'n':
+                c = '\n';
+                break;
+            case 'r':
+                c = '\r';
+                break;
+            case 't':
+                c = '\t';
+                break;
+            default:
                 throwJSONError("Bad escape", file, line, pos);
             }
+            // drop the escaped char
+            in.get();
+            ++pos;
         }
         ss << c;
         c = in.get();
@@ -656,10 +680,31 @@ StringElement::toJSON(std::ostream& ss) const {
         // Escape characters as defined in JSON spec
         // Note that we do not escape forward slash; this
         // is allowed, but not mandatory.
-        if (strchr("\"\\\b\f\n\r\t", c) != NULL) {
-            ss << '\\';
+        switch (c) {
+        case '"':
+            ss << '\\' << c;
+            break;
+        case '\\':
+            ss << '\\' << c;
+            break;
+        case '\b':
+            ss << '\\' << 'b';
+            break;
+        case '\f':
+            ss << '\\' << 'f';
+            break;
+        case '\n':
+            ss << '\\' << 'n';
+            break;
+        case '\r':
+            ss << '\\' << 'r';
+            break;
+        case '\t':
+            ss << '\\' << 't';
+            break;
+        default:
+            ss << c;
         }
-        ss << c;
     }
     ss << "\"";
 }

+ 5 - 5
src/lib/cc/tests/data_unittests.cc

@@ -321,11 +321,11 @@ TEST(Element, escape) {
     // String elements.
     escapeHelper("foo\"bar", "\"foo\\\"bar\"");
     escapeHelper("foo\\bar", "\"foo\\\\bar\"");
-    escapeHelper("foo\bbar", "\"foo\\\bbar\"");
-    escapeHelper("foo\fbar", "\"foo\\\fbar\"");
-    escapeHelper("foo\nbar", "\"foo\\\nbar\"");
-    escapeHelper("foo\rbar", "\"foo\\\rbar\"");
-    escapeHelper("foo\tbar", "\"foo\\\tbar\"");
+    escapeHelper("foo\bbar", "\"foo\\bbar\"");
+    escapeHelper("foo\fbar", "\"foo\\fbar\"");
+    escapeHelper("foo\nbar", "\"foo\\nbar\"");
+    escapeHelper("foo\rbar", "\"foo\\rbar\"");
+    escapeHelper("foo\tbar", "\"foo\\tbar\"");
     // Bad escapes
     EXPECT_THROW(Element::fromJSON("\\a"), JSONError);
     EXPECT_THROW(Element::fromJSON("\\"), JSONError);