From 561f8cf59ed14b1aa675b23d44e00d61c734b810 Mon Sep 17 00:00:00 2001 From: pantor Date: Mon, 19 Mar 2018 11:43:19 +0100 Subject: [PATCH] Catch some errors for conditional parsing --- src/inja.hpp | 18 +++++++++++++++--- test/src/unit-renderer.cpp | 7 +++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/inja.hpp b/src/inja.hpp index d4fbca6..1ea870c 100644 --- a/src/inja.hpp +++ b/src/inja.hpp @@ -769,6 +769,9 @@ public: const std::string loop_inner = match_statement.str(0); MatchType match_command = match(loop_inner, regex_map_loop); + if (not match_command.found()) { + inja_throw("parser_error", "unknown loop statement: " + loop_inner); + } switch (match_command.type()) { case Parsed::Loop::ForListIn: { const std::string value_name = match_command.str(1); @@ -785,9 +788,6 @@ public: result.emplace_back( std::make_shared(match_command.type(), key_name, value_name, parse_expression(list_name), loop_match.inner())); break; } - default: { - inja_throw("parser_error", "unknown loop statement: " + loop_inner); - } } break; } @@ -801,6 +801,9 @@ public: const std::string else_if_match_inner = else_if_match.open_match.str(1); MatchType match_command = match(else_if_match_inner, regex_map_condition); + if (not match_command.found()) { + inja_throw("parser_error", "unknown if statement: " + else_if_match.open_match.str()); + } condition_container->children.push_back( std::make_shared(else_if_match.inner(), match_command.type(), parse_expression(match_command.str(1))) ); else_if_match = search_closed_on_level(input, match_delimiter.regex(), regex_map_statement_openers.at(Parsed::Statement::Condition), regex_map_statement_closers.at(Parsed::Statement::Condition), regex_map_condition.at(Parsed::Condition::ElseIf), condition_match); @@ -812,13 +815,22 @@ public: const std::string else_match_inner = else_match.open_match.str(1); MatchType match_command = match(else_match_inner, regex_map_condition); + if (not match_command.found()) { + inja_throw("parser_error", "unknown if statement: " + else_match.open_match.str()); + } condition_container->children.push_back( std::make_shared(else_match.inner(), match_command.type(), parse_expression(match_command.str(1))) ); } MatchClosed last_if_match = search_closed(input, match_delimiter.regex(), regex_map_statement_openers.at(Parsed::Statement::Condition), regex_map_statement_closers.at(Parsed::Statement::Condition), condition_match); + if (not last_if_match.found()) { + inja_throw("parser_error", "misordered if statement"); + } const std::string last_if_match_inner = last_if_match.open_match.str(1); MatchType match_command = match(last_if_match_inner, regex_map_condition); + if (not match_command.found()) { + inja_throw("parser_error", "unknown if statement: " + last_if_match.open_match.str()); + } if (match_command.type() == Parsed::Condition::Else) { condition_container->children.push_back( std::make_shared(last_if_match.inner(), match_command.type()) ); } else { diff --git a/test/src/unit-renderer.cpp b/test/src/unit-renderer.cpp index 242d5dd..03e8f52 100644 --- a/test/src/unit-renderer.cpp +++ b/test/src/unit-renderer.cpp @@ -61,8 +61,8 @@ TEST_CASE("types") { CHECK( env.render("{% for name in empty_loop %}a{% endfor %}", data) == "" ); CHECK( env.render("{% for name in {} %}a{% endfor %}", data) == "" ); - CHECK_THROWS_WITH( env.render("{% for name ins names %}a{% endfor %}", data), "[inja.exception.parser_error] unknown loop statement: for name ins names" ); - // CHECK_THROWS_WITH( env.render("{% for name in relatives %}{{ name }}{% endfor %}", data), "[inja.exception.json_error] [json.exception.type_error.302] type must be array, but is object" ); + CHECK_THROWS_WITH( env.render("{% for name ins names %}a{% endfor %}", data), "[inja.exception.parser_error] unknown loop statement: for name ins names" ); + // CHECK_THROWS_WITH( env.render("{% for name in relatives %}{{ name }}{% endfor %}", data), "[inja.exception.json_error] [json.exception.type_error.302] type must be array, but is object" ); } SECTION("conditionals") { @@ -78,6 +78,9 @@ TEST_CASE("types") { CHECK( env.render("{% if age == 28 %}28{% else if age == 29 %}29{% endif %}", data) == "29" ); CHECK( env.render("{% if age == 26 %}26{% else if age == 27 %}27{% else if age == 28 %}28{% else %}29{% endif %}", data) == "29" ); CHECK( env.render("{% if age == 25 %}+{% endif %}{% if age == 29 %}+{% else %}-{% endif %}", data) == "+" ); + + CHECK_THROWS_WITH( env.render("{% if is_happy %}{% if is_happy %}{% endif %}", data), "[inja.exception.parser_error] misordered if statement" ); + CHECK_THROWS_WITH( env.render("{% if is_happy %}{% else if is_happy %}{% end if %}", data), "[inja.exception.parser_error] misordered if statement" ); } }