2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 05:55:28 +00:00

[1626] escape JSON strings correctly

This commit is contained in:
Jelte Jansen
2012-03-29 17:10:45 +02:00
parent 6a9dbeff7d
commit 63e4fc15cc
2 changed files with 56 additions and 5 deletions

View File

@@ -314,12 +314,21 @@ str_from_stringstream(std::istream &in, const std::string& file, const int line,
} else {
throwJSONError("String expected", file, line, pos);
}
while (c != EOF && c != '"') {
ss << c;
if (c == '\\' && in.peek() == '"') {
ss << in.get();
++pos;
if (c == '\\') {
// next char must be either another \ or "
// 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 {
std::cout << "[XX] cur string: " << ss.str() << std::endl;
throwJSONError(std::string("Bad escape for: ") + (char)in.peek(), file, line, pos);
}
}
ss << c;
c = in.get();
++pos;
}
@@ -642,7 +651,16 @@ NullElement::toJSON(std::ostream& ss) const {
void
StringElement::toJSON(std::ostream& ss) const {
ss << "\"";
ss << stringValue();
char c;
const std::string& str = stringValue();
for (size_t i = 0; i < str.size(); ++i) {
c = str[i];
// Escape characters as defined in JSON spec
if (strchr("\"\\/\b\f\n\r\t", c) != NULL) {
ss << '\\';
}
ss << c;
}
ss << "\"";
}

View File

@@ -20,6 +20,7 @@
using namespace isc::data;
#include <sstream>
#include <iostream>
using std::oct;
#include <iomanip>
@@ -299,6 +300,38 @@ TEST(Element, create_and_value_throws) {
}
// Helper for escape check; it puts the given string in a StringElement,
// then checks for the following conditions:
// stringValue() must be same as input
// toJSON() output must be escaped
// fromJSON() on the previous output must result in original input
void
escapeHelper(const std::string& input, const std::string& expected) {
StringElement str_element = StringElement(input);
EXPECT_EQ(input, str_element.stringValue());
std::stringstream os;
str_element.toJSON(os);
EXPECT_EQ(expected, os.str());
ElementPtr str_element2 = Element::fromJSON(os.str());
EXPECT_EQ(str_element.stringValue(), str_element2->stringValue());
}
TEST(Element, escape) {
// Test whether quotes are escaped correctly when creating direct
// String elements.
escapeHelper("foo\"bar", "\"foo\\\"bar\"");
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\"");
// Bad escapes
EXPECT_THROW(Element::fromJSON("\\a"), JSONError);
EXPECT_THROW(Element::fromJSON("\\"), JSONError);
}
TEST(Element, ListElement) {
// this function checks the specific functions for ListElements
ElementPtr el = Element::fromJSON("[ 1, \"bar\", 3 ]");