From 105096e75ad15a4338bf0d7277a514390ee19a8f Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Fri, 14 Feb 2025 14:55:36 +0000 Subject: [PATCH] LibJS: Stop executing successful regex if it's past the end of the input If the regex always matches the input, even if it's past the end, then we need to stop execution of the regex when it's past the end. This corresponds to step 13.a and prevents it from infinitely looping. Reduced from: https://github.com/Shopify/quilt/blob/d98672060fc724f3fe7af9a25a0845b8d7c0774a/packages/react-i18n/src/utilities/money.ts#L10-L14 --- Libraries/LibJS/Runtime/RegExpPrototype.cpp | 2 +- Libraries/LibJS/Tests/builtins/RegExp/RegExp.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) 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); +});