diff --git a/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Libraries/LibJS/Runtime/RegExpPrototype.cpp index e73987b6041..54a6decbf5d 100644 --- a/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -224,7 +224,7 @@ static ThrowCompletionOr regexp_builtin_exec(VM& vm, RegExpObject& regexp result = regex.match(string.view()); // 13.d and 13.a - if (!result.success) { + if (!result.success || last_index > string.length_in_code_units()) { // 13.d.i, 13.a.i if (sticky || global) TRY(regexp_object.set(vm.names.lastIndex, Value(0), Object::ShouldThrowExceptions::Yes)); diff --git a/Libraries/LibJS/Tests/builtins/RegExp/RegExp.js b/Libraries/LibJS/Tests/builtins/RegExp/RegExp.js index 0aa6e95ef13..8919584b5d2 100644 --- a/Libraries/LibJS/Tests/builtins/RegExp/RegExp.js +++ b/Libraries/LibJS/Tests/builtins/RegExp/RegExp.js @@ -66,3 +66,9 @@ test("Incorrectly escaped code units not converted to invalid patterns", () => { expect(re.test("⫀")).toBeTrue(); expect(re.test("\\u2abe")).toBeFalse(); // ⫀ is \u2abe }); + +test("regexp that always matches stops matching if it's past the end of the string instead of infinitely looping", () => { + const re = new RegExp("[\u200E]*", "gu"); + expect("whf".match(re)).toEqual(["", "", "", ""]); + expect(re.lastIndex).toBe(0); +});