diff --git a/src/lib/cc/data.cc b/src/lib/cc/data.cc index 612dc9c51e..e0bed90312 100644 --- a/src/lib/cc/data.cc +++ b/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 << "\""; } diff --git a/src/lib/cc/tests/data_unittests.cc b/src/lib/cc/tests/data_unittests.cc index 14e66416e9..79b53baa54 100644 --- a/src/lib/cc/tests/data_unittests.cc +++ b/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);