From 3dc0205ffa348840e022fa73b3596bcd45eb2a3d Mon Sep 17 00:00:00 2001 From: yhirose Date: Sun, 26 Jan 2020 23:00:37 -0500 Subject: [PATCH] Handle an invalid escape sequence char --- peglib.h | 3 +++ test/test.cc | 31 +++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/peglib.h b/peglib.h index cd782a8..bc14c39 100644 --- a/peglib.h +++ b/peglib.h @@ -383,6 +383,9 @@ inline std::string resolve_escape_sequence(const char* s, size_t n) { auto ch = s[i]; if (ch == '\\') { i++; + if (i == n) { + throw std::runtime_error("Invalid escape sequence..."); + } switch (s[i]) { case 'n': r += '\n'; i++; break; case 'r': r += '\r'; i++; break; diff --git a/test/test.cc b/test/test.cc index 29dc243..d288c53 100644 --- a/test/test.cc +++ b/test/test.cc @@ -20,10 +20,10 @@ TEST_CASE("Simple syntax test (with unicode)", "[general]") TEST_CASE("Simple syntax test", "[general]") { - peg::parser parser( - " ROOT <- _ " - " _ <- ' ' " - ); + peg::parser parser(R"( + ROOT <- _ + _ <- ' ' + )"); bool ret = parser; REQUIRE(ret == true); @@ -36,6 +36,28 @@ TEST_CASE("Empty syntax test", "[general]") REQUIRE(ret == false); } +TEST_CASE("Backslash escape sequence test", "[general]") +{ + peg::parser parser(R"( + ROOT <- _ + _ <- '\\' + )"); + + bool ret = parser; + REQUIRE(ret == true); +} + +TEST_CASE("Invalid escape sequence test", "[general]") +{ + peg::parser parser(R"( + ROOT <- _ + _ <- '\' + )"); + + bool ret = parser; + REQUIRE(ret == false); +} + TEST_CASE("Infinite loop 1", "[infinite loop]") { peg::parser pg(R"( @@ -1727,6 +1749,7 @@ TEST_CASE("PEG Literal", "[peg]") REQUIRE(exact(g, "Literal", "\"'\"abc\"'\" ") == false); REQUIRE(exact(g, "Literal", "abc") == false); REQUIRE(exact(g, "Literal", "") == false); + REQUIRE(exact(g, "Literal", "\\") == false); REQUIRE(exact(g, "Literal", u8"'日本語'") == true); REQUIRE(exact(g, "Literal", u8"\"日本語\"") == true); REQUIRE(exact(g, "Literal", u8"日本語") == false);