mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 10:08:10 +00:00
LibJS: Manually loop over escaped regex pattern instead of ::replace()
This makes it ever-so-slightly faster, but more importantly, it fixes the bug where a `/\//` regex's `source` property would return `\\/` ("\\\\/") instead of `\/` due to the existing '/' -> '\/' replace() call.
This commit is contained in:
parent
a8bcb901c0
commit
bcfbe0fbf7
2 changed files with 25 additions and 3 deletions
|
@ -248,8 +248,31 @@ DeprecatedString RegExpObject::escape_regexp_pattern() const
|
|||
// 3. Return S.
|
||||
if (m_pattern.is_empty())
|
||||
return "(?:)";
|
||||
|
||||
// FIXME: Check the 'u' and 'v' flags and escape accordingly
|
||||
return m_pattern.replace("\n"sv, "\\n"sv, ReplaceMode::All).replace("\r"sv, "\\r"sv, ReplaceMode::All).replace(LINE_SEPARATOR_STRING, "\\u2028"sv, ReplaceMode::All).replace(PARAGRAPH_SEPARATOR_STRING, "\\u2029"sv, ReplaceMode::All).replace("/"sv, "\\/"sv, ReplaceMode::All);
|
||||
StringBuilder builder;
|
||||
auto pattern = Utf8View { m_pattern };
|
||||
auto escaped = false;
|
||||
for (auto code_point : pattern) {
|
||||
if (escaped) {
|
||||
escaped = false;
|
||||
builder.append_code_point('\\');
|
||||
builder.append_code_point(code_point);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code_point == '\\') {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code_point == '\r' || code_point == LINE_SEPARATOR || code_point == PARAGRAPH_SEPARATOR || code_point == '/') {
|
||||
builder.append_code_point('\\');
|
||||
}
|
||||
builder.append_code_point(code_point);
|
||||
}
|
||||
|
||||
return builder.to_deprecated_string();
|
||||
}
|
||||
|
||||
// 22.2.3.2.4 RegExpCreate ( P, F ), https://tc39.es/ecma262/#sec-regexpcreate
|
||||
|
|
|
@ -3,6 +3,5 @@ test("basic functionality", () => {
|
|||
expect(RegExp().source).toBe("(?:)");
|
||||
expect(/test/.source).toBe("test");
|
||||
expect(/\n/.source).toBe("\\n");
|
||||
// FIXME: RegExp parse doesn't parse \/ :(
|
||||
// expect(/foo\/bar/.source).toBe("foo\\/bar");
|
||||
expect(/foo\/bar/.source).toBe("foo\\/bar");
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue