summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-11-30 17:46:53 +0330
committerAndreas Kling <kling@serenityos.org>2020-11-30 17:45:05 +0100
commit6394720c87cef4924e6045b2a3c6eba1d270c40d (patch)
tree6e62a3b45d5e95a5711c3486978a49fda690ca97
parent3bda4587355b1bad7388aa72672c79448fb40bab (diff)
downloadserenity-6394720c87cef4924e6045b2a3c6eba1d270c40d.zip
LibRegex: Don't try to consume the escaped character if at EOF
Fixes assert on e.g. `new RegExp("\\")`
-rw-r--r--Libraries/LibRegex/RegexParser.cpp8
-rw-r--r--Libraries/LibRegex/Tests/Regex.cpp44
2 files changed, 33 insertions, 19 deletions
diff --git a/Libraries/LibRegex/RegexParser.cpp b/Libraries/LibRegex/RegexParser.cpp
index 0cc6940b38..f342cce512 100644
--- a/Libraries/LibRegex/RegexParser.cpp
+++ b/Libraries/LibRegex/RegexParser.cpp
@@ -1114,6 +1114,9 @@ bool ECMA262Parser::parse_atom_escape(ByteCode& stack, size_t& match_length_mini
}
}
+ if (done())
+ return set_error(Error::InvalidTrailingEscape);
+
bool negate = false;
auto ch = parse_character_class_escape(negate);
if (!ch.has_value()) {
@@ -1211,6 +1214,11 @@ bool ECMA262Parser::parse_nonempty_class_ranges(Vector<CompareTypeAndValuePair>&
}
if (try_skip("\\")) {
+ if (done()) {
+ set_error(Error::InvalidTrailingEscape);
+ return {};
+ }
+
if (try_skip("f"))
return { { .code_point = '\f', .is_character_class = false } };
if (try_skip("n"))
diff --git a/Libraries/LibRegex/Tests/Regex.cpp b/Libraries/LibRegex/Tests/Regex.cpp
index 0e13744ea1..41f45e2232 100644
--- a/Libraries/LibRegex/Tests/Regex.cpp
+++ b/Libraries/LibRegex/Tests/Regex.cpp
@@ -474,27 +474,33 @@ TEST_CASE(simple_period_end_benchmark)
TEST_CASE(ECMA262_parse)
{
- constexpr const char* patterns[] {
- "^hello.$",
- "^(hello.)$",
- "^h{0,1}ello.$",
- "^hello\\W$",
- "^hell\\w.$",
- "^hell\\x6f1$", // ^hello1$
- "^hel(?:l\\w).$",
- "^hel(?<LO>l\\w).$",
- "^[-a-zA-Z\\w\\s]+$",
- "\\bhello\\B",
- "^[\\w+/_-]+[=]{0,2}$", // #4189
- "^(?:[^<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)", // #4189
- "\\/", // #4189
- ",/=-:", // #4243
- "\\x", // Even invalid escapes are allowed if ~unicode.
+ struct _test {
+ const char* pattern;
+ regex::Error expected_error { regex::Error::NoError };
};
- for (auto& pattern : patterns) {
- Regex<ECMA262> re(pattern);
- EXPECT_EQ(re.parser_result.error, Error::NoError);
+ constexpr _test tests[] {
+ { "^hello.$" },
+ { "^(hello.)$" },
+ { "^h{0,1}ello.$" },
+ { "^hello\\W$" },
+ { "^hell\\w.$" },
+ { "^hell\\x6f1$" }, // ^hello1$
+ { "^hel(?:l\\w).$" },
+ { "^hel(?<LO>l\\w).$" },
+ { "^[-a-zA-Z\\w\\s]+$" },
+ { "\\bhello\\B" },
+ { "^[\\w+/_-]+[=]{0,2}$" }, // #4189
+ { "^(?:[^<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)" }, // #4189
+ { "\\/" }, // #4189
+ { ",/=-:" }, // #4243
+ { "\\x" }, // Even invalid escapes are allowed if ~unicode.
+ { "\\", regex::Error::InvalidTrailingEscape },
+ };
+
+ for (auto& test : tests) {
+ Regex<ECMA262> re(test.pattern);
+ EXPECT_EQ(re.parser_result.error, test.expected_error);
#ifdef REGEX_DEBUG
dbg() << "\n";
RegexDebug regex_dbg(stderr);