tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit a6cac184cf434c0324f8e22994c923547b98cbcf
parent 3ceca4002d238c37211adcf88224938b15a5f620
Author: Daniel Minor <dminor@mozilla.com>
Date:   Tue, 25 Nov 2025 19:12:07 +0000

Bug 1998177 - Don't call well-known Symbol methods for regexp on primitives; r=jandem

Differential Revision: https://phabricator.services.mozilla.com/D273154

Diffstat:
Mjs/src/builtin/String.js | 69++++++++++++++++++---------------------------------------------------
Djs/src/jit-test/tests/basic/bug1549035.js | 11-----------
Djs/src/jit-test/tests/fuses/string-proto-symbols-3.js | 19-------------------
Mjs/src/jit-test/tests/ion/testStringMatch.js | 18------------------
Mjs/src/tests/jstests.list | 25-------------------------
5 files changed, 18 insertions(+), 124 deletions(-)

diff --git a/js/src/builtin/String.js b/js/src/builtin/String.js @@ -14,14 +14,10 @@ function String_match(regexp) { } // Step 2. - var isPatternString = typeof regexp === "string"; - if ( - !(isPatternString && CanOptimizeStringProtoSymbolLookup()) && - !IsNullOrUndefined(regexp) - ) { + if (IsObject(regexp)) { // Fast path for regular expressions with the original // RegExp.prototype[@@match] function. - if (IsObject(regexp) && IsOptimizableRegExpObject(regexp)) { + if (IsOptimizableRegExpObject(regexp)) { return callFunction(RegExpMatch, regexp, this); } @@ -30,9 +26,6 @@ function String_match(regexp) { // Step 2.b. if (matcher !== undefined) { - if (!IsObject(regexp)) { - RegExpSymbolProtocolOnPrimitiveCounter(); - } return callContentFunction(matcher, regexp, this); } } @@ -40,7 +33,7 @@ function String_match(regexp) { // Step 3. var S = ToString(this); - if (isPatternString && IsRegExpPrototypeOptimizable()) { + if (typeof regexp === "string" && IsRegExpPrototypeOptimizable()) { var flatResult = FlatStringMatch(S, regexp); if (flatResult !== undefined) { return flatResult; @@ -69,7 +62,7 @@ function String_matchAll(regexp) { } // Step 2. - if (!IsNullOrUndefined(regexp)) { + if (IsObject(regexp)) { // Steps 2.a-b. if (IsRegExp(regexp)) { // Step 2.b.i. @@ -88,7 +81,7 @@ function String_matchAll(regexp) { // Fast path for regular expressions with the original // RegExp.prototype[@@matchAll] function. - if (IsObject(regexp) && IsOptimizableRegExpObject(regexp)) { + if (IsOptimizableRegExpObject(regexp)) { return callFunction(RegExpMatchAll, regexp, this); } @@ -97,9 +90,6 @@ function String_matchAll(regexp) { // Step 2.d. if (matcher !== undefined) { - if (!IsObject(regexp)) { - RegExpSymbolProtocolOnPrimitiveCounter(); - } return callContentFunction(matcher, regexp, this); } } @@ -212,13 +202,10 @@ function String_replace(searchValue, replaceValue) { } // Step 2. - if ( - !(typeof searchValue === "string" && CanOptimizeStringProtoSymbolLookup()) && - !IsNullOrUndefined(searchValue) - ) { + if (IsObject(searchValue)) { // Fast path for regular expressions with the original // RegExp.prototype[@@replace] function. - if (IsObject(searchValue) && IsOptimizableRegExpObject(searchValue)) { + if (IsOptimizableRegExpObject(searchValue)) { return callFunction(RegExpReplace, searchValue, this, replaceValue); } @@ -227,9 +214,6 @@ function String_replace(searchValue, replaceValue) { // Step 2.b. if (replacer !== undefined) { - if (!IsObject(searchValue)) { - RegExpSymbolProtocolOnPrimitiveCounter(); - } return callContentFunction(replacer, searchValue, this, replaceValue); } } @@ -294,7 +278,7 @@ function String_replaceAll(searchValue, replaceValue) { } // Step 2. - if (!IsNullOrUndefined(searchValue)) { + if (IsObject(searchValue)) { // Steps 2.a-b. if (IsRegExp(searchValue)) { // Step 2.b.i. @@ -313,7 +297,7 @@ function String_replaceAll(searchValue, replaceValue) { // Fast path for regular expressions with the original // RegExp.prototype[@@replace] function. - if (IsObject(searchValue) && IsOptimizableRegExpObject(searchValue)) { + if (IsOptimizableRegExpObject(searchValue)) { return callFunction(RegExpReplace, searchValue, this, replaceValue); } @@ -322,9 +306,6 @@ function String_replaceAll(searchValue, replaceValue) { // Step 2.b. if (replacer !== undefined) { - if (!IsObject(searchValue)) { - RegExpSymbolProtocolOnPrimitiveCounter(); - } return callContentFunction(replacer, searchValue, this, replaceValue); } } @@ -425,13 +406,10 @@ function String_search(regexp) { // Step 2. var isPatternString = typeof regexp === "string"; - if ( - !(isPatternString && CanOptimizeStringProtoSymbolLookup()) && - !IsNullOrUndefined(regexp) - ) { + if (IsObject(regexp)) { // Fast path for regular expressions with the original // RegExp.prototype[@@search] function. - if (IsObject(regexp) && IsOptimizableRegExpObject(regexp)) { + if (IsOptimizableRegExpObject(regexp)) { return callFunction(RegExpSearch, regexp, this); } @@ -440,9 +418,6 @@ function String_search(regexp) { // Step 2.b. if (searcher !== undefined) { - if (!IsObject(regexp)) { - RegExpSymbolProtocolOnPrimitiveCounter(); - } return callContentFunction(searcher, regexp, this); } } @@ -479,25 +454,20 @@ function String_split(separator, limit) { // are constants. Following sequence of if's cannot be put together in // order that IonMonkey sees the constant if present (bug 1246141). if (typeof this === "string") { - if (CanOptimizeStringProtoSymbolLookup()) { - if (typeof separator === "string") { - if (limit === undefined) { - // inlineConstantStringSplitString needs both arguments to - // be MConstant, so pass them directly. - return StringSplitString(this, separator); - } + if (typeof separator === "string") { + if (limit === undefined) { + // inlineConstantStringSplitString needs both arguments to + // be MConstant, so pass them directly. + return StringSplitString(this, separator); } } } // Step 2. - if ( - !(typeof separator === "string" && CanOptimizeStringProtoSymbolLookup()) && - !IsNullOrUndefined(separator) - ) { + if (IsObject(separator)) { // Fast path for regular expressions with the original // RegExp.prototype[@@split] function. - if (IsObject(separator) && IsOptimizableRegExpObject(separator)) { + if (IsOptimizableRegExpObject(separator)) { return callFunction(RegExpSplit, separator, this, limit); } @@ -506,9 +476,6 @@ function String_split(separator, limit) { // Step 2.b. if (splitter !== undefined) { - if (!IsObject(separator)) { - RegExpSymbolProtocolOnPrimitiveCounter(); - } return callContentFunction(splitter, separator, this, limit); } } diff --git a/js/src/jit-test/tests/basic/bug1549035.js b/js/src/jit-test/tests/basic/bug1549035.js @@ -1,11 +0,0 @@ -var expected = 2; -for (var i = 0; i < 100; ++i) { - if (i === 50) { - expected = 0; - String.prototype[Symbol.split] = function() { - return []; - }; - } - var r = "ab".split(""); - assertEq(r.length, expected); -} diff --git a/js/src/jit-test/tests/fuses/string-proto-symbols-3.js b/js/src/jit-test/tests/fuses/string-proto-symbols-3.js @@ -1,19 +0,0 @@ -// |jit-test| --fast-warmup; --no-threads - -// Test invalidation of Ion code when StringPrototypeSymbols fuse is popped. -function test() { - var s = "foobar"; - var count = 0; - for (var i = 0; i < 200; i++) { - s.replace("abc", "").replace("def", ""); - if (i === 150) { - // Pop the fuse. - Object.prototype[Symbol.replace] = function() { - count++; - return s; - }; - } - } - assertEq(count, 98); -} -test(); diff --git a/js/src/jit-test/tests/ion/testStringMatch.js b/js/src/jit-test/tests/ion/testStringMatch.js @@ -37,24 +37,6 @@ function testMod(apply, unapply) { } } } -testMod(() => { - String.prototype[Symbol.match] = () => ["mod"]; -}, () => { - delete String.prototype[Symbol.match]; -}); -testMod(() => { - Object.prototype[Symbol.match] = () => ["mod"]; -}, () => { - delete Object.prototype[Symbol.match]; -}); - -testMod(() => { - Object.setPrototypeOf(String.prototype, { - [Symbol.match]: () => ["mod"] - }); -}, () => { - Object.setPrototypeOf(String.prototype, Object.prototype); -}); var orig_exec = RegExp.prototype.exec; testMod(() => { diff --git a/js/src/tests/jstests.list b/js/src/tests/jstests.list @@ -662,31 +662,6 @@ skip script test262/language/statements/with/set-mutable-binding-idref-compound- skip script test262/built-ins/Iterator/concat/fresh-iterator-result.js skip script test262/built-ins/Iterator/concat/next-method-returns-throwing-value.js -# https://bugzilla.mozilla.org/show_bug.cgi?id=1950211 -skip script test262/built-ins/String/prototype/replace/cstm-replace-on-boolean-primitive.js -skip script test262/built-ins/String/prototype/replace/cstm-replace-on-string-primitive.js -skip script test262/built-ins/String/prototype/replace/cstm-replace-on-number-primitive.js -skip script test262/built-ins/String/prototype/replace/cstm-replace-on-bigint-primitive.js -skip script test262/built-ins/String/prototype/matchAll/cstm-matchall-on-number-primitive.js -skip script test262/built-ins/String/prototype/matchAll/cstm-matchall-on-bigint-primitive.js -skip script test262/built-ins/String/prototype/matchAll/cstm-matchall-on-string-primitive.js -skip script test262/built-ins/String/prototype/replaceAll/cstm-replaceall-on-bigint-primitive.js -skip script test262/built-ins/String/prototype/replaceAll/cstm-replaceall-on-number-primitive.js -skip script test262/built-ins/String/prototype/replaceAll/cstm-replaceall-on-boolean-primitive.js -skip script test262/built-ins/String/prototype/replaceAll/cstm-replaceall-on-string-primitive.js -skip script test262/built-ins/String/prototype/split/cstm-split-on-boolean-primitive.js -skip script test262/built-ins/String/prototype/split/cstm-split-on-string-primitive.js -skip script test262/built-ins/String/prototype/split/cstm-split-on-number-primitive.js -skip script test262/built-ins/String/prototype/split/cstm-split-on-bigint-primitive.js -skip script test262/built-ins/String/prototype/match/cstm-matcher-on-boolean-primitive.js -skip script test262/built-ins/String/prototype/match/cstm-matcher-on-bigint-primitive.js -skip script test262/built-ins/String/prototype/match/cstm-matcher-on-number-primitive.js -skip script test262/built-ins/String/prototype/match/cstm-matcher-on-string-primitive.js -skip script test262/built-ins/String/prototype/search/cstm-search-on-bigint-primitive.js -skip script test262/built-ins/String/prototype/search/cstm-search-on-string-primitive.js -skip script test262/built-ins/String/prototype/search/cstm-search-on-boolean-primitive.js -skip script test262/built-ins/String/prototype/search/cstm-search-on-number-primitive.js - # https://bugzilla.mozilla.org/show_bug.cgi?id=1970162 # https://github.com/tc39/ecma402/pull/989 skip script test262/intl402/PluralRules/constructor-options-throwing-getters.js