mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:37:46 +00:00
LibJS: Fix replaceAll crash for overlapping search string positions
The implementation of String.prototype.replaceAll cannot use AK's implementation of String::find_all when finding the indices of the search string in the source string. String::find_all will return indices [0, 1] for String("aaa").find_all("aa") - i.e. it returns overlapping results. This is not allowed by the JavaScript specification for replaceAll.
This commit is contained in:
parent
30615ac2bb
commit
424c7eaa40
2 changed files with 14 additions and 2 deletions
|
@ -877,9 +877,16 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all)
|
||||||
if (vm.exception())
|
if (vm.exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
Vector<size_t> match_positions = string.find_all(search_string);
|
Vector<size_t> match_positions;
|
||||||
size_t end_of_last_match = 0;
|
size_t advance_by = max(1u, search_string.length());
|
||||||
|
auto position = string.find(search_string);
|
||||||
|
|
||||||
|
while (position.has_value()) {
|
||||||
|
match_positions.append(*position);
|
||||||
|
position = string.find(search_string, *position + advance_by);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t end_of_last_match = 0;
|
||||||
StringBuilder result;
|
StringBuilder result;
|
||||||
|
|
||||||
for (auto position : match_positions) {
|
for (auto position : match_positions) {
|
||||||
|
|
|
@ -59,6 +59,11 @@ test("basic regex replacement", () => {
|
||||||
|
|
||||||
expect("abc123def".replaceAll(/\D/g, "*")).toBe("***123***");
|
expect("abc123def".replaceAll(/\D/g, "*")).toBe("***123***");
|
||||||
expect("123abc456".replaceAll(/\D/g, "*")).toBe("123***456");
|
expect("123abc456".replaceAll(/\D/g, "*")).toBe("123***456");
|
||||||
|
|
||||||
|
expect("aaab a a aac".replaceAll("aa", "z")).toBe("zab a a zc");
|
||||||
|
expect("aaab a a aac".replaceAll("aa", "a")).toBe("aab a a ac");
|
||||||
|
expect("aaab a a aac".replaceAll("a", "a")).toBe("aaab a a aac");
|
||||||
|
expect("aaab a a aac".replaceAll("a", "z")).toBe("zzzb z z zzc");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("functional regex replacement", () => {
|
test("functional regex replacement", () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue