diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 29d20760d0..14e7880547 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -399,7 +399,14 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_replace) if (vm.exception()) return {}; } else { - replacement = get_substitution(global_object, matched, string, position, captures, named_captures, replace_value); + auto named_captures_object = js_undefined(); + if (!named_captures.is_undefined()) { + named_captures_object = named_captures.to_object(global_object); + if (vm.exception()) + return {}; + } + + replacement = get_substitution(global_object, matched, string, position, captures, named_captures_object, replace_value); if (vm.exception()) return {}; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.replace.js b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.replace.js index a570a68ad0..16d481c9f8 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.replace.js +++ b/Userland/Libraries/LibJS/Tests/builtins/String/String.prototype.replace.js @@ -139,3 +139,19 @@ test("replacement with substitution", () => { expect("abc".replace(/(?a)b(?c)/, "$")).toBe("c"); expect("abc".replace(/(?a)b(?c)/, "$b$")).toBe("cba"); }); + +test("replacement with substitution and 'groups' coerced to an object", () => { + var r = /./; + var coercibleValue = { + length: 1, + 0: "b", + index: 1, + groups: "123", + }; + + r.exec = function () { + return coercibleValue; + }; + + expect(r[Symbol.replace]("ab", "[$]")).toBe("a[3]"); +});