From 82b95ca664ebc33c3a704156286179e493e6a6a1 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 20 Jun 2017 20:14:18 +0200 Subject: [PATCH] :hammer: simplified error handling in parser --- src/json.hpp | 60 +++++++++--------- test/src/unit-class_parser.cpp | 112 ++++++++++++++++----------------- 2 files changed, 87 insertions(+), 85 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index b4dc422d..13a31bda 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -12902,7 +12902,7 @@ scan_number_done: default: { // the last token was unexpected - unexpect(last_token); + unexpect(); } } @@ -13040,51 +13040,49 @@ scan_number_done: /// get next token from lexer typename lexer::token_type get_token() { - last_token = m_lexer.scan(); - return last_token; + return (last_token = m_lexer.scan()); } /*! @throw parse_error.101 if expected token did not occur */ - void expect(typename lexer::token_type t) const + void expect(typename lexer::token_type t) { if (JSON_UNLIKELY(t != last_token)) { - std::string error_msg = "syntax error - "; - if (last_token == lexer::token_type::parse_error) - { - error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + m_lexer.get_token_string() + "'"; - } - else - { - error_msg += "unexpected " + std::string(lexer::token_type_name(last_token)); - } - - error_msg += "; expected " + std::string(lexer::token_type_name(t)); - JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg)); + errored = true; + expected = t; + throw_exception(); } } /*! @throw parse_error.101 if unexpected token occurred */ - void unexpect(typename lexer::token_type t) const + void unexpect() { - if (JSON_UNLIKELY(t == last_token)) - { - std::string error_msg = "syntax error - "; - if (last_token == lexer::token_type::parse_error) - { - error_msg += std::string(m_lexer.get_error_message()) + "; last read '" + m_lexer.get_token_string() + "'"; - } - else - { - error_msg += "unexpected " + std::string(lexer::token_type_name(last_token)); - } + errored = true; + throw_exception(); + } - JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg)); + [[noreturn]] void throw_exception() const + { + std::string error_msg = "syntax error - "; + if (last_token == lexer::token_type::parse_error) + { + error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" + m_lexer.get_token_string() + "'"; } + else + { + error_msg += "unexpected " + std::string(lexer::token_type_name(last_token)); + } + + if (expected != lexer::token_type::uninitialized) + { + error_msg += "; expected " + std::string(lexer::token_type_name(expected)); + } + + JSON_THROW(parse_error::create(101, m_lexer.get_position(), error_msg)); } private: @@ -13096,6 +13094,10 @@ scan_number_done: typename lexer::token_type last_token = lexer::token_type::uninitialized; /// the lexer lexer m_lexer; + /// whether a syntax error occurred + bool errored = false; + /// possible reason for the syntax error + typename lexer::token_type expected = lexer::token_type::uninitialized; }; public: diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp index 920054d2..3a71dfa4 100644 --- a/test/src/unit-class_parser.cpp +++ b/test/src/unit-class_parser.cpp @@ -98,18 +98,18 @@ TEST_CASE("parser class") // error: tab in string CHECK_THROWS_AS(parse_string("\"\t\"").parse(), json::parse_error); CHECK_THROWS_WITH(parse_string("\"\t\"").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read '\"'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"'"); // error: newline in string CHECK_THROWS_AS(parse_string("\"\n\"").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\"\r\"").parse(), json::parse_error); CHECK_THROWS_WITH(parse_string("\"\n\"").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read '\"'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"'"); CHECK_THROWS_WITH(parse_string("\"\r\"").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read '\"'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"'"); // error: backspace in string CHECK_THROWS_AS(parse_string("\"\b\"").parse(), json::parse_error); CHECK_THROWS_WITH(parse_string("\"\b\"").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read '\"'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: control character must be escaped; last read: '\"'"); // improve code coverage CHECK_THROWS_AS(parse_string("\uFF01").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("[-4:1,]").parse(), json::parse_error); @@ -317,21 +317,21 @@ TEST_CASE("parser class") CHECK_THROWS_WITH(parse_string("-01").parse(), "[json.exception.parse_error.101] parse error at 3: syntax error - unexpected number literal; expected end of input"); CHECK_THROWS_WITH(parse_string("--1").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '--'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '--'"); CHECK_THROWS_WITH(parse_string("1.").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read '1.'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '1.'"); CHECK_THROWS_WITH(parse_string("1E").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1E'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E'"); CHECK_THROWS_WITH(parse_string("1E-").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after exponent sign; last read '1E-'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after exponent sign; last read: '1E-'"); CHECK_THROWS_WITH(parse_string("1.E1").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read '1.E'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '1.E'"); CHECK_THROWS_WITH(parse_string("-1E").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '-1E'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '-1E'"); CHECK_THROWS_WITH(parse_string("-0E#").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '-0E#'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '-0E#'"); CHECK_THROWS_WITH(parse_string("-0E-#").parse(), - "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read '-0E-#'"); + "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0E-#'"); CHECK_THROWS_WITH(parse_string("-0#").parse(), "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; last read: '-0#'; expected end of input"); CHECK_THROWS_WITH(parse_string("-0.0:").parse(), @@ -343,7 +343,7 @@ TEST_CASE("parser class") CHECK_THROWS_WITH(parse_string("-0e0-:").parse(), "[json.exception.parse_error.101] parse error at 6: syntax error - invalid number; expected digit after '-'; last read: '-:'; expected end of input"); CHECK_THROWS_WITH(parse_string("-0e-:").parse(), - "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read '-0e-:'"); + "[json.exception.parse_error.101] parse error at 5: syntax error - invalid number; expected digit after exponent sign; last read: '-0e-:'"); CHECK_THROWS_WITH(parse_string("-0f").parse(), "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read: '-0f'; expected end of input"); } @@ -630,55 +630,55 @@ TEST_CASE("parser class") CHECK_THROWS_AS(parse_string("1E/").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("1E:").parse(), json::parse_error); CHECK_THROWS_WITH(parse_string("0.").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read '0.'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '0.'"); CHECK_THROWS_WITH(parse_string("-").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '-'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-'"); CHECK_THROWS_WITH(parse_string("--").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '--'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '--'"); CHECK_THROWS_WITH(parse_string("-0.").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after '.'; last read '-0.'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid number; expected digit after '.'; last read: '-0.'"); CHECK_THROWS_WITH(parse_string("-.").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '-.'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-.'"); CHECK_THROWS_WITH(parse_string("-:").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read '-:'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid number; expected digit after '-'; last read: '-:'"); CHECK_THROWS_WITH(parse_string("0.:").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read '0.:'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected digit after '.'; last read: '0.:'"); CHECK_THROWS_WITH(parse_string("e.").parse(), - "[json.exception.parse_error.101] parse error at 1: syntax error - invalid literal; last read 'e'"); + "[json.exception.parse_error.101] parse error at 1: syntax error - invalid literal; last read: 'e'"); CHECK_THROWS_WITH(parse_string("1e.").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1e.'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e.'"); CHECK_THROWS_WITH(parse_string("1e/").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1e/'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e/'"); CHECK_THROWS_WITH(parse_string("1e:").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1e:'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1e:'"); CHECK_THROWS_WITH(parse_string("1E.").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1E.'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E.'"); CHECK_THROWS_WITH(parse_string("1E/").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1E/'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E/'"); CHECK_THROWS_WITH(parse_string("1E:").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read '1E:'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid number; expected '+', '-', or digit after exponent; last read: '1E:'"); // unexpected end of null CHECK_THROWS_AS(parse_string("n").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("nu").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("nul").parse(), json::parse_error); CHECK_THROWS_WITH(parse_string("n").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'null'; last read 'n'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'null'; last read: 'n'"); CHECK_THROWS_WITH(parse_string("nu").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'null'; last read 'nu'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'null'; last read: 'nu'"); CHECK_THROWS_WITH(parse_string("nul").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'null'; last read 'nul'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'null'; last read: 'nul'"); // unexpected end of true CHECK_THROWS_AS(parse_string("t").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("tr").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("tru").parse(), json::parse_error); CHECK_THROWS_WITH(parse_string("t").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'true'; last read 't'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'true'; last read: 't'"); CHECK_THROWS_WITH(parse_string("tr").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'true'; last read 'tr'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'true'; last read: 'tr'"); CHECK_THROWS_WITH(parse_string("tru").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'true'; last read 'tru'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'true'; last read: 'tru'"); // unexpected end of false CHECK_THROWS_AS(parse_string("f").parse(), json::parse_error); @@ -686,13 +686,13 @@ TEST_CASE("parser class") CHECK_THROWS_AS(parse_string("fal").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("fals").parse(), json::parse_error); CHECK_THROWS_WITH(parse_string("f").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'false'; last read 'f'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid literal; expected 'false'; last read: 'f'"); CHECK_THROWS_WITH(parse_string("fa").parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'false'; last read 'fa'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid literal; expected 'false'; last read: 'fa'"); CHECK_THROWS_WITH(parse_string("fal").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read 'fal'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid literal; expected 'false'; last read: 'fal'"); CHECK_THROWS_WITH(parse_string("fals").parse(), - "[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; expected 'false'; last read 'fals'"); + "[json.exception.parse_error.101] parse error at 5: syntax error - invalid literal; expected 'false'; last read: 'fals'"); // missing/unexpected end of array CHECK_THROWS_AS(parse_string("[").parse(), json::parse_error); @@ -743,25 +743,25 @@ TEST_CASE("parser class") CHECK_THROWS_AS(parse_string("\"\\u01").parse(), json::parse_error); CHECK_THROWS_AS(parse_string("\"\\u012").parse(), json::parse_error); CHECK_THROWS_WITH(parse_string("\"").parse(), - "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: missing closing quote; last read '\"'"); + "[json.exception.parse_error.101] parse error at 2: syntax error - invalid string: missing closing quote; last read: '\"'"); CHECK_THROWS_WITH(parse_string("\"\\\"").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: missing closing quote; last read '\"\\\"'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: missing closing quote; last read: '\"\\\"'"); CHECK_THROWS_WITH(parse_string("\"\\u\"").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u\"'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u\"'"); CHECK_THROWS_WITH(parse_string("\"\\u0\"").parse(), - "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u0\"'"); + "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0\"'"); CHECK_THROWS_WITH(parse_string("\"\\u01\"").parse(), - "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u01\"'"); + "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01\"'"); CHECK_THROWS_WITH(parse_string("\"\\u012\"").parse(), - "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u012\"'"); + "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012\"'"); CHECK_THROWS_WITH(parse_string("\"\\u").parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u'"); CHECK_THROWS_WITH(parse_string("\"\\u0").parse(), - "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u0'"); + "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u0'"); CHECK_THROWS_WITH(parse_string("\"\\u01").parse(), - "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u01'"); + "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u01'"); CHECK_THROWS_WITH(parse_string("\"\\u012").parse(), - "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '\"\\u012'"); + "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '\"\\u012'"); // invalid escapes for (int c = 1; c < 128; ++c) @@ -798,7 +798,7 @@ TEST_CASE("parser class") if (c > 0x1f) { CHECK_THROWS_WITH(parse_string(s.c_str()).parse(), - "[json.exception.parse_error.101] parse error at 3: syntax error - invalid string: forbidden character after backslash; last read '\"\\" + std::string(1, static_cast(c)) + "'"); + "[json.exception.parse_error.101] parse error at 3: syntax error - invalid string: forbidden character after backslash; last read: '\"\\" + std::string(1, static_cast(c)) + "'"); } break; } @@ -874,7 +874,7 @@ TEST_CASE("parser class") if (c > 0x1f) { CHECK_THROWS_WITH(parse_string(s1.c_str()).parse(), - "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '" + s1.substr(0, 7) + "'"); + "[json.exception.parse_error.101] parse error at 7: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s1.substr(0, 7) + "'"); } CAPTURE(s2); @@ -883,7 +883,7 @@ TEST_CASE("parser class") if (c > 0x1f) { CHECK_THROWS_WITH(parse_string(s2.c_str()).parse(), - "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '" + s2.substr(0, 6) + "'"); + "[json.exception.parse_error.101] parse error at 6: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s2.substr(0, 6) + "'"); } CAPTURE(s3); @@ -892,7 +892,7 @@ TEST_CASE("parser class") if (c > 0x1f) { CHECK_THROWS_WITH(parse_string(s3.c_str()).parse(), - "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '" + s3.substr(0, 5) + "'"); + "[json.exception.parse_error.101] parse error at 5: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s3.substr(0, 5) + "'"); } CAPTURE(s4); @@ -901,7 +901,7 @@ TEST_CASE("parser class") if (c > 0x1f) { CHECK_THROWS_WITH(parse_string(s4.c_str()).parse(), - "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read '" + s4.substr(0, 4) + "'"); + "[json.exception.parse_error.101] parse error at 4: syntax error - invalid string: '\\u' must be followed by 4 hex digits; last read: '" + s4.substr(0, 4) + "'"); } } } @@ -910,17 +910,17 @@ TEST_CASE("parser class") // missing part of a surrogate pair CHECK_THROWS_AS(json::parse("\"\\uD80C\""), json::parse_error); CHECK_THROWS_WITH(json::parse("\"\\uD80C\""), - "[json.exception.parse_error.101] parse error at 8: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read '\"\\uD80C\"'"); + "[json.exception.parse_error.101] parse error at 8: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\"'"); // invalid surrogate pair CHECK_THROWS_AS(json::parse("\"\\uD80C\\uD80C\""), json::parse_error); CHECK_THROWS_AS(json::parse("\"\\uD80C\\u0000\""), json::parse_error); CHECK_THROWS_AS(json::parse("\"\\uD80C\\uFFFF\""), json::parse_error); CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uD80C\""), - "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read '\"\\uD80C\\uD80C'"); + "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uD80C'"); CHECK_THROWS_WITH(json::parse("\"\\uD80C\\u0000\""), - "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read '\"\\uD80C\\u0000'"); + "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\u0000'"); CHECK_THROWS_WITH(json::parse("\"\\uD80C\\uFFFF\""), - "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read '\"\\uD80C\\uFFFF'"); + "[json.exception.parse_error.101] parse error at 13: syntax error - invalid string: surrogate U+DC00..U+DFFF must be followed by U+DC00..U+DFFF; last read: '\"\\uD80C\\uFFFF'"); } SECTION("parse errors (accept)")