| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 91ef427 commit ac8d2de
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -37,7 +37,6 @@ const { | |||
| 37 | 37 | ObjectDefineProperty, | |
| 38 | 38 | Promise, | |
| 39 | 39 | ReflectApply, | |
| 40 | - RegExpPrototypeExec, | ||
| 41 | 40 | SafeMap, | |
| 42 | 41 | SafeSet, | |
| 43 | 42 | String, | |
@@ -89,6 +88,7 @@ const { | |||
| 89 | 88 | promisify: { | |
| 90 | 89 | custom: kCustomPromisifiedSymbol, | |
| 91 | 90 | }, | |
| 91 | + SideEffectFreeRegExpPrototypeExec, | ||
| 92 | 92 | } = require('internal/util'); | |
| 93 | 93 | const { | |
| 94 | 94 | constants: { | |
@@ -2410,7 +2410,7 @@ if (isWindows) { | |||
| 2410 | 2410 | // slash. | |
| 2411 | 2411 | const splitRootRe = /^(?:[a-zA-Z]:|[\\/]{2}[^\\/]+[\\/][^\\/]+)?[\\/]*/; | |
| 2412 | 2412 | splitRoot = function splitRoot(str) { | |
| 2413 | - return RegExpPrototypeExec(splitRootRe, str)[0]; | ||
| 2413 | + return SideEffectFreeRegExpPrototypeExec(splitRootRe, str)[0]; | ||
| 2414 | 2414 | }; | |
| 2415 | 2415 | } else { | |
| 2416 | 2416 | splitRoot = function splitRoot(str) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,7 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | + const { RegExpPrototypeExec } = primordials; | ||
| 4 | + | ||
| 3 | 5 | const { | |
| 4 | 6 | prepareMainThreadExecution | |
| 5 | 7 | } = require('internal/bootstrap/pre_execution'); | |
@@ -8,6 +10,9 @@ prepareMainThreadExecution(true); | |||
| 8 | 10 | ||
| 9 | 11 | markBootstrapComplete(); | |
| 10 | 12 | ||
| 13 | + // Necessary to reset RegExp statics before user code runs. | ||
| 14 | + RegExpPrototypeExec(/^/, ''); | ||
| 15 | + | ||
| 11 | 16 | // Note: this loads the module through the ESM loader if the module is | |
| 12 | 17 | // determined to be an ES module. This hangs from the CJS module loader | |
| 13 | 18 | // because we currently allow monkey-patching of the module loaders | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,6 +9,7 @@ const { | |||
| 9 | 9 | ArrayPrototypeSplice, | |
| 10 | 10 | ObjectDefineProperty, | |
| 11 | 11 | PromisePrototypeThen, | |
| 12 | + RegExpPrototypeExec, | ||
| 12 | 13 | globalThis: { Atomics }, | |
| 13 | 14 | } = primordials; | |
| 14 | 15 | ||
@@ -266,4 +267,7 @@ process._fatalException = workerOnGlobalUncaughtException; | |||
| 266 | 267 | ||
| 267 | 268 | markBootstrapComplete(); | |
| 268 | 269 | ||
| 270 | + // Necessary to reset RegExp statics before user code runs. | ||
| 271 | + RegExpPrototypeExec(/^/, ''); | ||
| 272 | + | ||
| 269 | 273 | port.start(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,7 @@ const { | |||
| 11 | 11 | SafeArrayIterator, | |
| 12 | 12 | SafeMap, | |
| 13 | 13 | SafeSet, | |
| 14 | - StringPrototypeReplace, | ||
| 14 | + StringPrototypeReplaceAll, | ||
| 15 | 15 | StringPrototypeSlice, | |
| 16 | 16 | StringPrototypeStartsWith, | |
| 17 | 17 | SyntaxErrorPrototype, | |
@@ -144,14 +144,13 @@ function enrichCJSError(err, content, filename) { | |||
| 144 | 144 | ||
| 145 | 145 | // Strategy for loading a node-style CommonJS module | |
| 146 | 146 | const isWindows = process.platform === 'win32'; | |
| 147 | - const winSepRegEx = /\//g; | ||
| 148 | 147 | translators.set('commonjs', async function commonjsStrategy(url, source, | |
| 149 | 148 | isMain) { | |
| 150 | 149 | debug(`Translating CJSModule ${url}`); | |
| 151 | 150 | ||
| 152 | 151 | let filename = internalURLModule.fileURLToPath(new URL(url)); | |
| 153 | 152 | if (isWindows) | |
| 154 | - filename = StringPrototypeReplace(filename, winSepRegEx, '\\'); | ||
| 153 | + filename = StringPrototypeReplaceAll(filename, '/', '\\'); | ||
| 155 | 154 | ||
| 156 | 155 | if (!cjsParse) await initCJSParse(); | |
| 157 | 156 | const { module, exportNames } = cjsPreparseModuleExports(filename); | |
@@ -274,7 +273,7 @@ translators.set('json', async function jsonStrategy(url, source) { | |||
| 274 | 273 | let module; | |
| 275 | 274 | if (pathname) { | |
| 276 | 275 | modulePath = isWindows ? | |
| 277 | - StringPrototypeReplace(pathname, winSepRegEx, '\\') : pathname; | ||
| 276 | + StringPrototypeReplaceAll(pathname, '/', '\\') : pathname; | ||
| 278 | 277 | module = CJSModule._cache[modulePath]; | |
| 279 | 278 | if (module && module.loaded) { | |
| 280 | 279 | const exports = module.exports; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,7 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | + RegExpPrototypeExec, | ||
| 4 | 5 | globalThis, | |
| 5 | 6 | } = primordials; | |
| 6 | 7 | ||
@@ -45,6 +46,7 @@ function evalModule(source, print) { | |||
| 45 | 46 | } | |
| 46 | 47 | const { loadESM } = require('internal/process/esm_loader'); | |
| 47 | 48 | const { handleMainPromise } = require('internal/modules/run_main'); | |
| 49 | + RegExpPrototypeExec(/^/, ''); // Necessary to reset RegExp statics before user code runs. | ||
| 48 | 50 | return handleMainPromise(loadESM((loader) => loader.eval(source))); | |
| 49 | 51 | } | |
| 50 | 52 | ||
@@ -72,6 +74,7 @@ function evalScript(name, body, breakFirstLine, print) { | |||
| 72 | 74 | return (main) => main(); | |
| 73 | 75 | `; | |
| 74 | 76 | globalThis.__filename = name; | |
| 77 | + RegExpPrototypeExec(/^/, ''); // Necessary to reset RegExp statics before user code runs. | ||
| 75 | 78 | const result = module._compile(script, `${name}-wrapper`)(() => | |
| 76 | 79 | require('vm').runInThisContext(body, { | |
| 77 | 80 | filename: name, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,7 @@ const { | |||
| 23 | 23 | StringPrototypeCharCodeAt, | |
| 24 | 24 | StringPrototypeIncludes, | |
| 25 | 25 | StringPrototypeReplace, | |
| 26 | + StringPrototypeReplaceAll, | ||
| 26 | 27 | StringPrototypeSlice, | |
| 27 | 28 | StringPrototypeSplit, | |
| 28 | 29 | StringPrototypeStartsWith, | |
@@ -1372,8 +1373,6 @@ function urlToHttpOptions(url) { | |||
| 1372 | 1373 | return options; | |
| 1373 | 1374 | } | |
| 1374 | 1375 | ||
| 1375 | - const forwardSlashRegEx = /\//g; | ||
| 1376 | - | ||
| 1377 | 1376 | function getPathFromURLWin32(url) { | |
| 1378 | 1377 | const hostname = url.hostname; | |
| 1379 | 1378 | let pathname = url.pathname; | |
@@ -1388,7 +1387,7 @@ function getPathFromURLWin32(url) { | |||
| 1388 | 1387 | } | |
| 1389 | 1388 | } | |
| 1390 | 1389 | } | |
| 1391 | - pathname = pathname.replace(forwardSlashRegEx, '\\'); | ||
| 1390 | + pathname = StringPrototypeReplaceAll(pathname, '/', '\\'); | ||
| 1392 | 1391 | pathname = decodeURIComponent(pathname); | |
| 1393 | 1392 | if (hostname !== '') { | |
| 1394 | 1393 | // If hostname is set, then we have a UNC path | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,6 +7,7 @@ const { | |||
| 7 | 7 | ArrayPrototypeSlice, | |
| 8 | 8 | ArrayPrototypeSort, | |
| 9 | 9 | Error, | |
| 10 | + FunctionPrototypeCall, | ||
| 10 | 11 | ObjectCreate, | |
| 11 | 12 | ObjectDefineProperties, | |
| 12 | 13 | ObjectDefineProperty, | |
@@ -554,6 +555,21 @@ function setOwnProperty(obj, key, value) { | |||
| 554 | 555 | }); | |
| 555 | 556 | } | |
| 556 | 557 | ||
| 558 | + let internalGlobal; | ||
| 559 | + function getInternalGlobal() { | ||
| 560 | + if (internalGlobal == null) { | ||
| 561 | + // Lazy-load to avoid a circular dependency. | ||
| 562 | + const { runInNewContext } = require('vm'); | ||
| 563 | + internalGlobal = runInNewContext('this', undefined, { contextName: 'internal' }); | ||
| 564 | + } | ||
| 565 | + return internalGlobal; | ||
| 566 | + } | ||
| 567 | + | ||
| 568 | + function SideEffectFreeRegExpPrototypeExec(regex, string) { | ||
| 569 | + const { RegExp: RegExpFromAnotherRealm } = getInternalGlobal(); | ||
| 570 | + return FunctionPrototypeCall(RegExpFromAnotherRealm.prototype.exec, regex, string); | ||
| 571 | + } | ||
| 572 | + | ||
| 557 | 573 | module.exports = { | |
| 558 | 574 | assertCrypto, | |
| 559 | 575 | cachedResult, | |
@@ -568,6 +584,7 @@ module.exports = { | |||
| 568 | 584 | filterDuplicateStrings, | |
| 569 | 585 | filterOwnProperties, | |
| 570 | 586 | getConstructorOf, | |
| 587 | + getInternalGlobal, | ||
| 571 | 588 | getSystemErrorMap, | |
| 572 | 589 | getSystemErrorName, | |
| 573 | 590 | isError, | |
@@ -577,6 +594,7 @@ module.exports = { | |||
| 577 | 594 | normalizeEncoding, | |
| 578 | 595 | once, | |
| 579 | 596 | promisify, | |
| 597 | + SideEffectFreeRegExpPrototypeExec, | ||
| 580 | 598 | sleep, | |
| 581 | 599 | spliceOne, | |
| 582 | 600 | structuredClone, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,68 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const assert = require('node:assert'); | ||
| 5 | + const { spawnSync, spawn } = require('node:child_process'); | ||
| 6 | + | ||
| 7 | + assert.strictEqual(RegExp.$_, ''); | ||
| 8 | + assert.strictEqual(RegExp.$0, undefined); | ||
| 9 | + assert.strictEqual(RegExp.$1, ''); | ||
| 10 | + assert.strictEqual(RegExp.$2, ''); | ||
| 11 | + assert.strictEqual(RegExp.$3, ''); | ||
| 12 | + assert.strictEqual(RegExp.$4, ''); | ||
| 13 | + assert.strictEqual(RegExp.$5, ''); | ||
| 14 | + assert.strictEqual(RegExp.$6, ''); | ||
| 15 | + assert.strictEqual(RegExp.$7, ''); | ||
| 16 | + assert.strictEqual(RegExp.$8, ''); | ||
| 17 | + assert.strictEqual(RegExp.$9, ''); | ||
| 18 | + assert.strictEqual(RegExp.input, ''); | ||
| 19 | + assert.strictEqual(RegExp.lastMatch, ''); | ||
| 20 | + assert.strictEqual(RegExp.lastParen, ''); | ||
| 21 | + assert.strictEqual(RegExp.leftContext, ''); | ||
| 22 | + assert.strictEqual(RegExp.rightContext, ''); | ||
| 23 | + assert.strictEqual(RegExp['$&'], ''); | ||
| 24 | + assert.strictEqual(RegExp['$`'], ''); | ||
| 25 | + assert.strictEqual(RegExp['$+'], ''); | ||
| 26 | + assert.strictEqual(RegExp["$'"], ''); | ||
| 27 | + | ||
| 28 | + const allRegExpStatics = | ||
| 29 | + 'RegExp.$_ + RegExp["$&"] + RegExp["$`"] + RegExp["$+"] + RegExp["$\'"] + ' + | ||
| 30 | + 'RegExp.input + RegExp.lastMatch + RegExp.lastParen + ' + | ||
| 31 | + 'RegExp.leftContext + RegExp.rightContext + ' + | ||
| 32 | + Array.from({ length: 10 }, (_, i) => `RegExp.$${i}`).join(' + '); | ||
| 33 | + | ||
| 34 | + { | ||
| 35 | + const child = spawnSync(process.execPath, | ||
| 36 | + [ '-p', allRegExpStatics ], | ||
| 37 | + { stdio: ['inherit', 'pipe', 'inherit'] }); | ||
| 38 | + assert.match(child.stdout.toString(), /^undefined\r?\n$/); | ||
| 39 | + assert.strictEqual(child.status, 0); | ||
| 40 | + assert.strictEqual(child.signal, null); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + { | ||
| 44 | + const child = spawnSync(process.execPath, | ||
| 45 | + [ '-e', `console.log(${allRegExpStatics})`, '--input-type=module' ], | ||
| 46 | + { stdio: ['inherit', 'pipe', 'inherit'] }); | ||
| 47 | + assert.match(child.stdout.toString(), /^undefined\r?\n$/); | ||
| 48 | + assert.strictEqual(child.status, 0); | ||
| 49 | + assert.strictEqual(child.signal, null); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + { | ||
| 53 | + const child = spawn(process.execPath, [], { stdio: ['pipe', 'pipe', 'inherit'], encoding: 'utf8' }); | ||
| 54 | + | ||
| 55 | + let stdout = ''; | ||
| 56 | + child.stdout.on('data', (chunk) => { | ||
| 57 | + stdout += chunk; | ||
| 58 | + }); | ||
| 59 | + | ||
| 60 | + child.on('exit', common.mustCall((status, signal) => { | ||
| 61 | + assert.match(stdout, /^undefined\r?\n$/); | ||
| 62 | + assert.strictEqual(status, 0); | ||
| 63 | + assert.strictEqual(signal, null); | ||
| 64 | + })); | ||
| 65 | + child.on('error', common.mustNotCall()); | ||
| 66 | + | ||
| 67 | + child.stdin.end(`console.log(${allRegExpStatics});\n`); | ||
| 68 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,26 @@ | |||
| 1 | + // We must load the CJS version here because the ESM wrapper call `hasIPv6` | ||
| 2 | + // which compiles a RegEx. | ||
| 3 | + // eslint-disable-next-line node-core/require-common-first | ||
| 4 | + import '../common/index.js'; | ||
| 5 | + import assert from 'node:assert'; | ||
| 6 | + | ||
| 7 | + assert.strictEqual(RegExp.$_, ''); | ||
| 8 | + assert.strictEqual(RegExp.$0, undefined); | ||
| 9 | + assert.strictEqual(RegExp.$1, ''); | ||
| 10 | + assert.strictEqual(RegExp.$2, ''); | ||
| 11 | + assert.strictEqual(RegExp.$3, ''); | ||
| 12 | + assert.strictEqual(RegExp.$4, ''); | ||
| 13 | + assert.strictEqual(RegExp.$5, ''); | ||
| 14 | + assert.strictEqual(RegExp.$6, ''); | ||
| 15 | + assert.strictEqual(RegExp.$7, ''); | ||
| 16 | + assert.strictEqual(RegExp.$8, ''); | ||
| 17 | + assert.strictEqual(RegExp.$9, ''); | ||
| 18 | + assert.strictEqual(RegExp.input, ''); | ||
| 19 | + assert.strictEqual(RegExp.lastMatch, ''); | ||
| 20 | + assert.strictEqual(RegExp.lastParen, ''); | ||
| 21 | + assert.strictEqual(RegExp.leftContext, ''); | ||
| 22 | + assert.strictEqual(RegExp.rightContext, ''); | ||
| 23 | + assert.strictEqual(RegExp['$&'], ''); | ||
| 24 | + assert.strictEqual(RegExp['$`'], ''); | ||
| 25 | + assert.strictEqual(RegExp['$+'], ''); | ||
| 26 | + assert.strictEqual(RegExp["$'"], ''); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,6 @@ expectExperimentalWarning(); | |||
| 23 | 23 | // We must hold on to the contexts here so that they | |
| 24 | 24 | // don't get GC'ed until the measurement is complete | |
| 25 | 25 | assert.strictEqual(arr.length, count); | |
| 26 | - assertDetailedShape(result, count); | ||
| 26 | + assertDetailedShape(result, count + common.isWindows); | ||
| 27 | 27 | })); | |
| 28 | 28 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments