Skip to content

Commit 6394720

Browse files
alimpfardawesomekling
authored andcommitted
LibRegex: Don't try to consume the escaped character if at EOF
Fixes assert on e.g. `new RegExp("\\")`
1 parent 3bda458 commit 6394720

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed

Libraries/LibRegex/RegexParser.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,9 @@ bool ECMA262Parser::parse_atom_escape(ByteCode& stack, size_t& match_length_mini
11141114
}
11151115
}
11161116

1117+
if (done())
1118+
return set_error(Error::InvalidTrailingEscape);
1119+
11171120
bool negate = false;
11181121
auto ch = parse_character_class_escape(negate);
11191122
if (!ch.has_value()) {
@@ -1211,6 +1214,11 @@ bool ECMA262Parser::parse_nonempty_class_ranges(Vector<CompareTypeAndValuePair>&
12111214
}
12121215

12131216
if (try_skip("\\")) {
1217+
if (done()) {
1218+
set_error(Error::InvalidTrailingEscape);
1219+
return {};
1220+
}
1221+
12141222
if (try_skip("f"))
12151223
return { { .code_point = '\f', .is_character_class = false } };
12161224
if (try_skip("n"))

Libraries/LibRegex/Tests/Regex.cpp

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -474,27 +474,33 @@ TEST_CASE(simple_period_end_benchmark)
474474

475475
TEST_CASE(ECMA262_parse)
476476
{
477-
constexpr const char* patterns[] {
478-
"^hello.$",
479-
"^(hello.)$",
480-
"^h{0,1}ello.$",
481-
"^hello\\W$",
482-
"^hell\\w.$",
483-
"^hell\\x6f1$", // ^hello1$
484-
"^hel(?:l\\w).$",
485-
"^hel(?<LO>l\\w).$",
486-
"^[-a-zA-Z\\w\\s]+$",
487-
"\\bhello\\B",
488-
"^[\\w+/_-]+[=]{0,2}$", // #4189
489-
"^(?:[^<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)", // #4189
490-
"\\/", // #4189
491-
",/=-:", // #4243
492-
"\\x", // Even invalid escapes are allowed if ~unicode.
477+
struct _test {
478+
const char* pattern;
479+
regex::Error expected_error { regex::Error::NoError };
493480
};
494481

495-
for (auto& pattern : patterns) {
496-
Regex<ECMA262> re(pattern);
497-
EXPECT_EQ(re.parser_result.error, Error::NoError);
482+
constexpr _test tests[] {
483+
{ "^hello.$" },
484+
{ "^(hello.)$" },
485+
{ "^h{0,1}ello.$" },
486+
{ "^hello\\W$" },
487+
{ "^hell\\w.$" },
488+
{ "^hell\\x6f1$" }, // ^hello1$
489+
{ "^hel(?:l\\w).$" },
490+
{ "^hel(?<LO>l\\w).$" },
491+
{ "^[-a-zA-Z\\w\\s]+$" },
492+
{ "\\bhello\\B" },
493+
{ "^[\\w+/_-]+[=]{0,2}$" }, // #4189
494+
{ "^(?:[^<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)" }, // #4189
495+
{ "\\/" }, // #4189
496+
{ ",/=-:" }, // #4243
497+
{ "\\x" }, // Even invalid escapes are allowed if ~unicode.
498+
{ "\\", regex::Error::InvalidTrailingEscape },
499+
};
500+
501+
for (auto& test : tests) {
502+
Regex<ECMA262> re(test.pattern);
503+
EXPECT_EQ(re.parser_result.error, test.expected_error);
498504
#ifdef REGEX_DEBUG
499505
dbg() << "\n";
500506
RegexDebug regex_dbg(stderr);

0 commit comments

Comments
 (0)