diff --git a/src/json.hpp b/src/json.hpp index c405ba0c0..dccf768af 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2476,7 +2476,7 @@ class basic_json unsigned int yyaccept = 0; static const unsigned char yybm[] = { - 64, 64, 64, 64, 64, 64, 64, 64, + 0, 64, 64, 64, 64, 64, 64, 64, 64, 192, 192, 64, 64, 192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, @@ -2650,6 +2650,10 @@ json_parser_7: json_parser_8: yyaccept = 0; yych = *(m_marker = ++m_cursor); + if (yych <= 0x00) + { + goto json_parser_6; + } goto json_parser_53; json_parser_9: ++m_cursor; @@ -2955,6 +2959,10 @@ json_parser_53: { goto json_parser_52; } + if (yych <= 0x00) + { + goto json_parser_29; + } if (yych <= '"') { goto json_parser_55; diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 1bfe3a2d7..63e7e1d5c 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2514,7 +2514,7 @@ class basic_json // string quotation_mark = [\"]; escape = [\\]; - unescaped = [^\"\\]; + unescaped = [^\"\\\000]; escaped = escape ([\"\\/bfnrt] | [u][0-9a-fA-F]{4}); char = unescaped | escaped; string = quotation_mark char* quotation_mark; diff --git a/test/unit.cpp b/test/unit.cpp index fd1523410..cb6919ee1 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -4044,7 +4044,7 @@ TEST_CASE("lexer class") switch (c) { - // characters that are prefixes of reasonable json + // single characters that are valid tokens case ('['): case (']'): case ('{'): @@ -4066,12 +4066,6 @@ TEST_CASE("lexer class") break; } - case ('"'): - { - // no idea what to do here - break; - } - // whitespace case (' '): case ('\t'): @@ -4199,32 +4193,37 @@ TEST_CASE("parser class") SECTION("parse errors") { // unexpected end of number - CHECK_THROWS_AS(json::parser("0.A").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("-,").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("-A").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("0.").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("-").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("--").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("-0.").parse(), std::invalid_argument); // unexpected end of null CHECK_THROWS_AS(json::parser("n").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("nA").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("nuA").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("nulA").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("n").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("nu").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("nul").parse(), std::invalid_argument); // unexpected end of true CHECK_THROWS_AS(json::parser("t").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("tA").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("trA").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("truA").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("t").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("tr").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("tru").parse(), std::invalid_argument); // unexpected end of false CHECK_THROWS_AS(json::parser("f").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("faA").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("falA").parse(), std::invalid_argument); - CHECK_THROWS_AS(json::parser("falsA").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("fa").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("fal").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("fals").parse(), std::invalid_argument); // unexpected end of array + CHECK_THROWS_AS(json::parser("[1,").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("[1,]").parse(), std::invalid_argument); // unexpected end of object + CHECK_THROWS_AS(json::parser("{").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("{\"foo\"").parse(), std::invalid_argument); + CHECK_THROWS_AS(json::parser("{\"foo\":").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("{\"foo\":}").parse(), std::invalid_argument); CHECK_THROWS_AS(json::parser("{\"foo\":1,}").parse(), std::invalid_argument); }