diff --git a/.gitignore b/.gitignore index a434324f..bfba1a89 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ json_unit html + +benchmark diff --git a/src/json.hpp b/src/json.hpp index 89fd9a41..04bd1acd 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2251,7 +2251,7 @@ class basic_json { // control characters (everything between 0x00 and 0x1f) // -> create four-digit hex representation - std::stringstream ss; + std::basic_stringstream ss; ss << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(c); result += ss.str(); } @@ -2391,7 +2391,7 @@ class basic_json // 15 digits of precision allows round-trip IEEE 754 // string->double->string const auto sz = static_cast(std::snprintf(nullptr, 0, "%.15g", m_value.number_float)); - std::vector buf(sz + 1); + std::vector buf(sz + 1); std::snprintf(&buf[0], buf.size(), "%.15g", m_value.number_float); return string_t(buf.data()); } @@ -4577,21 +4577,19 @@ basic_json_parser_59: result += "\r"; break; } - - // characters that are not "un"escsaped case '\\': { - result += "\\\\"; + result += "\\"; break; } case '/': { - result += "\\/"; + result += "/"; break; } case '"': { - result += "\\\""; + result += "\""; break; } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index d2414298..48682339 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2251,7 +2251,7 @@ class basic_json { // control characters (everything between 0x00 and 0x1f) // -> create four-digit hex representation - std::stringstream ss; + std::basic_stringstream ss; ss << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(c); result += ss.str(); } @@ -2391,7 +2391,7 @@ class basic_json // 15 digits of precision allows round-trip IEEE 754 // string->double->string const auto sz = static_cast(std::snprintf(nullptr, 0, "%.15g", m_value.number_float)); - std::vector buf(sz + 1); + std::vector buf(sz + 1); std::snprintf(&buf[0], buf.size(), "%.15g", m_value.number_float); return string_t(buf.data()); } @@ -3883,21 +3883,19 @@ class basic_json result += "\r"; break; } - - // characters that are not "un"escsaped case '\\': { - result += "\\\\"; + result += "\\"; break; } case '/': { - result += "\\/"; + result += "/"; break; } case '"': { - result += "\\\""; + result += "\""; break; } diff --git a/test/unit.cpp b/test/unit.cpp index 92360fb5..f3fe37d4 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -7328,12 +7328,12 @@ TEST_CASE("parser class") SECTION("escaped") { - // quotation mark - CHECK(json::parser("\"\\\"\"").parse() == json("\\\"")); - // reverse solidus - CHECK(json::parser("\"\\\\\"").parse() == json("\\\\")); + // quotation mark "\"" + CHECK(json::parser("\"\\\"\"").parse() == R"("\"")"_json); + // reverse solidus "\\" + CHECK(json::parser("\"\\\\\"").parse() == R"("\\")"_json); // solidus - CHECK(json::parser("\"\\/\"").parse() == json("\\/")); + CHECK(json::parser("\"\\/\"").parse() == R"("/")"_json); // backspace CHECK(json::parser("\"\\b\"").parse() == json("\b")); // formfeed @@ -8267,3 +8267,16 @@ TEST_CASE("concepts") } } } + +TEST_CASE("regression tests") +{ + SECTION("issue #60 - Double quotation mark is not parsed correctly") + { + SECTION("escape_dobulequote") + { + auto s = "[\"\\\"foo\\\"\"]"; + json j = json::parse(s); + CHECK(j == R"(["\"foo\""])"_json); + } + } +}