11cb0ef41Sopenharmony_ci// Flags: --expose-internals 21cb0ef41Sopenharmony_ci'use strict'; 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_ciconst { mustNotCall } = require('../common'); 51cb0ef41Sopenharmony_ciconst assert = require('assert'); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciconst { 81cb0ef41Sopenharmony_ci RegExpPrototypeExec, 91cb0ef41Sopenharmony_ci RegExpPrototypeSymbolReplace, 101cb0ef41Sopenharmony_ci RegExpPrototypeSymbolSearch, 111cb0ef41Sopenharmony_ci RegExpPrototypeSymbolSplit, 121cb0ef41Sopenharmony_ci SafeStringPrototypeSearch, 131cb0ef41Sopenharmony_ci hardenRegExp, 141cb0ef41Sopenharmony_ci} = require('internal/test/binding').primordials; 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ciconst { 171cb0ef41Sopenharmony_ci SideEffectFreeRegExpPrototypeExec, 181cb0ef41Sopenharmony_ci SideEffectFreeRegExpPrototypeSymbolReplace, 191cb0ef41Sopenharmony_ci SideEffectFreeRegExpPrototypeSymbolSplit, 201cb0ef41Sopenharmony_ci} = require('internal/util'); 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciObject.defineProperties(RegExp.prototype, { 241cb0ef41Sopenharmony_ci [Symbol.match]: { 251cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%[@@match]'), 261cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%[@@match]'), 271cb0ef41Sopenharmony_ci }, 281cb0ef41Sopenharmony_ci [Symbol.matchAll]: { 291cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%[@@matchAll]'), 301cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%[@@matchAll]'), 311cb0ef41Sopenharmony_ci }, 321cb0ef41Sopenharmony_ci [Symbol.replace]: { 331cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%[@@replace]'), 341cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%[@@replace]'), 351cb0ef41Sopenharmony_ci }, 361cb0ef41Sopenharmony_ci [Symbol.search]: { 371cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%[@@search]'), 381cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%[@@search]'), 391cb0ef41Sopenharmony_ci }, 401cb0ef41Sopenharmony_ci [Symbol.split]: { 411cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%[@@split]'), 421cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%[@@split]'), 431cb0ef41Sopenharmony_ci }, 441cb0ef41Sopenharmony_ci dotAll: { 451cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.dotAll'), 461cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.dotAll'), 471cb0ef41Sopenharmony_ci }, 481cb0ef41Sopenharmony_ci exec: { 491cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.exec'), 501cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.exec'), 511cb0ef41Sopenharmony_ci }, 521cb0ef41Sopenharmony_ci flags: { 531cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.flags'), 541cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.flags'), 551cb0ef41Sopenharmony_ci }, 561cb0ef41Sopenharmony_ci global: { 571cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.global'), 581cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.global'), 591cb0ef41Sopenharmony_ci }, 601cb0ef41Sopenharmony_ci hasIndices: { 611cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.hasIndices'), 621cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.hasIndices'), 631cb0ef41Sopenharmony_ci }, 641cb0ef41Sopenharmony_ci ignoreCase: { 651cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.ignoreCase'), 661cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.ignoreCase'), 671cb0ef41Sopenharmony_ci }, 681cb0ef41Sopenharmony_ci multiline: { 691cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.multiline'), 701cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.multiline'), 711cb0ef41Sopenharmony_ci }, 721cb0ef41Sopenharmony_ci source: { 731cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.source'), 741cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.source'), 751cb0ef41Sopenharmony_ci }, 761cb0ef41Sopenharmony_ci sticky: { 771cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.sticky'), 781cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.sticky'), 791cb0ef41Sopenharmony_ci }, 801cb0ef41Sopenharmony_ci test: { 811cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.test'), 821cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.test'), 831cb0ef41Sopenharmony_ci }, 841cb0ef41Sopenharmony_ci toString: { 851cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.toString'), 861cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.toString'), 871cb0ef41Sopenharmony_ci }, 881cb0ef41Sopenharmony_ci unicode: { 891cb0ef41Sopenharmony_ci get: mustNotCall('get %RegExp.prototype%.unicode'), 901cb0ef41Sopenharmony_ci set: mustNotCall('set %RegExp.prototype%.unicode'), 911cb0ef41Sopenharmony_ci }, 921cb0ef41Sopenharmony_ci}); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_cihardenRegExp(hardenRegExp(/1/)); 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci// IMO there are no valid use cases in node core to use RegExpPrototypeSymbolMatch 971cb0ef41Sopenharmony_ci// or RegExpPrototypeSymbolMatchAll, they are inherently unsafe. 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ciassert.strictEqual(RegExpPrototypeExec(/foo/, 'bar'), null); 1001cb0ef41Sopenharmony_ciassert.strictEqual(RegExpPrototypeExec(hardenRegExp(/foo/), 'bar'), null); 1011cb0ef41Sopenharmony_ciassert.strictEqual(SideEffectFreeRegExpPrototypeExec(/foo/, 'bar'), null); 1021cb0ef41Sopenharmony_ciassert.strictEqual(SideEffectFreeRegExpPrototypeExec(hardenRegExp(/foo/), 'bar'), null); 1031cb0ef41Sopenharmony_ci{ 1041cb0ef41Sopenharmony_ci const expected = ['bar']; 1051cb0ef41Sopenharmony_ci Object.defineProperties(expected, { 1061cb0ef41Sopenharmony_ci index: { __proto__: null, configurable: true, writable: true, enumerable: true, value: 0 }, 1071cb0ef41Sopenharmony_ci input: { __proto__: null, configurable: true, writable: true, enumerable: true, value: 'bar' }, 1081cb0ef41Sopenharmony_ci groups: { __proto__: null, configurable: true, writable: true, enumerable: true }, 1091cb0ef41Sopenharmony_ci }); 1101cb0ef41Sopenharmony_ci const actual = SideEffectFreeRegExpPrototypeExec(/bar/, 'bar'); 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci // assert.deepStrictEqual(actual, expected) doesn't work for cross-realm comparison. 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ci assert.strictEqual(Array.isArray(actual), Array.isArray(expected)); 1151cb0ef41Sopenharmony_ci assert.deepStrictEqual(Reflect.ownKeys(actual), Reflect.ownKeys(expected)); 1161cb0ef41Sopenharmony_ci for (const key of Reflect.ownKeys(expected)) { 1171cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1181cb0ef41Sopenharmony_ci Reflect.getOwnPropertyDescriptor(actual, key), 1191cb0ef41Sopenharmony_ci Reflect.getOwnPropertyDescriptor(expected, key), 1201cb0ef41Sopenharmony_ci ); 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci} 1231cb0ef41Sopenharmony_ci{ 1241cb0ef41Sopenharmony_ci const myRegex = hardenRegExp(/a/); 1251cb0ef41Sopenharmony_ci assert.strictEqual(RegExpPrototypeSymbolReplace(myRegex, 'baar', 'e'), 'bear'); 1261cb0ef41Sopenharmony_ci} 1271cb0ef41Sopenharmony_ci{ 1281cb0ef41Sopenharmony_ci const myRegex = /a/; 1291cb0ef41Sopenharmony_ci assert.strictEqual(SideEffectFreeRegExpPrototypeSymbolReplace(myRegex, 'baar', 'e'), 'bear'); 1301cb0ef41Sopenharmony_ci} 1311cb0ef41Sopenharmony_ci{ 1321cb0ef41Sopenharmony_ci const myRegex = hardenRegExp(/a/g); 1331cb0ef41Sopenharmony_ci assert.strictEqual(RegExpPrototypeSymbolReplace(myRegex, 'baar', 'e'), 'beer'); 1341cb0ef41Sopenharmony_ci} 1351cb0ef41Sopenharmony_ci{ 1361cb0ef41Sopenharmony_ci const myRegex = /a/g; 1371cb0ef41Sopenharmony_ci assert.strictEqual(SideEffectFreeRegExpPrototypeSymbolReplace(myRegex, 'baar', 'e'), 'beer'); 1381cb0ef41Sopenharmony_ci} 1391cb0ef41Sopenharmony_ci{ 1401cb0ef41Sopenharmony_ci const myRegex = hardenRegExp(/a/); 1411cb0ef41Sopenharmony_ci assert.strictEqual(RegExpPrototypeSymbolSearch(myRegex, 'baar'), 1); 1421cb0ef41Sopenharmony_ci} 1431cb0ef41Sopenharmony_ci{ 1441cb0ef41Sopenharmony_ci const myRegex = /a/; 1451cb0ef41Sopenharmony_ci assert.strictEqual(SafeStringPrototypeSearch('baar', myRegex), 1); 1461cb0ef41Sopenharmony_ci} 1471cb0ef41Sopenharmony_ci{ 1481cb0ef41Sopenharmony_ci const myRegex = hardenRegExp(/a/); 1491cb0ef41Sopenharmony_ci assert.deepStrictEqual(RegExpPrototypeSymbolSplit(myRegex, 'baar', 0), []); 1501cb0ef41Sopenharmony_ci} 1511cb0ef41Sopenharmony_ci{ 1521cb0ef41Sopenharmony_ci const myRegex = /a/; 1531cb0ef41Sopenharmony_ci const expected = []; 1541cb0ef41Sopenharmony_ci const actual = SideEffectFreeRegExpPrototypeSymbolSplit(myRegex, 'baar', 0); 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_ci // assert.deepStrictEqual(actual, expected) doesn't work for cross-realm comparison. 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci assert.strictEqual(Array.isArray(actual), Array.isArray(expected)); 1591cb0ef41Sopenharmony_ci assert.deepStrictEqual(Reflect.ownKeys(actual), Reflect.ownKeys(expected)); 1601cb0ef41Sopenharmony_ci for (const key of Reflect.ownKeys(expected)) { 1611cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1621cb0ef41Sopenharmony_ci Reflect.getOwnPropertyDescriptor(actual, key), 1631cb0ef41Sopenharmony_ci Reflect.getOwnPropertyDescriptor(expected, key), 1641cb0ef41Sopenharmony_ci ); 1651cb0ef41Sopenharmony_ci } 1661cb0ef41Sopenharmony_ci} 1671cb0ef41Sopenharmony_ci{ 1681cb0ef41Sopenharmony_ci const myRegex = hardenRegExp(/a/); 1691cb0ef41Sopenharmony_ci assert.deepStrictEqual(RegExpPrototypeSymbolSplit(myRegex, 'baar', 1), ['b']); 1701cb0ef41Sopenharmony_ci} 1711cb0ef41Sopenharmony_ci{ 1721cb0ef41Sopenharmony_ci const myRegex = hardenRegExp(/a/); 1731cb0ef41Sopenharmony_ci assert.deepStrictEqual(RegExpPrototypeSymbolSplit(myRegex, 'baar'), ['b', '', 'r']); 1741cb0ef41Sopenharmony_ci} 175