Skip to content

lib: limit split function calls to prevent excessive array length #57501

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/internal/blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ function resolveObjectURL(url) {
try {
const parsed = new URL(url);

const split = StringPrototypeSplit(parsed.pathname, ':');
const split = StringPrototypeSplit(parsed.pathname, ':', 3);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to improve the performance, we should actually do the splitting manually by checking with indexOf and slicing out the variables we need. The same applies to multiple other places here.

This particular case will only improve the performance in case the pathname is rather untypical.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to do that in another pass, same for replacements where we can just use replaceAll

Can I do that or would you like to combine them all?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And btw current behavior rejects if more than 1 occurrence of : is found, so using split here kinda makes sense to get that number before continuing further


if (split.length !== 2)
return;
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/debugger/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class NodeInspector {
this[domain] = createAgentProxy(domain, this.client);
});
this.handleDebugEvent = (fullName, params) => {
const { 0: domain, 1: name } = StringPrototypeSplit(fullName, '.');
const { 0: domain, 1: name } = StringPrototypeSplit(fullName, '.', 2);
if (domain in this) {
this[domain].emit(name, params);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ const fatalExceptionStackEnhancers = {
// ANSI escape sequences is not reliable.
if (isWindows) {
const info = internalBinding('os').getOSInformation();
const ver = ArrayPrototypeMap(StringPrototypeSplit(info[2], '.'),
const ver = ArrayPrototypeMap(StringPrototypeSplit(info[2], '.', 3),
Number);
if (ver[0] !== 10 || ver[2] < 14393) {
useColors = false;
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -1833,7 +1833,7 @@ function reconstructErrorStack(err, parentPath, parentSource) {
const { 1: line, 2: col } =
RegExpPrototypeExec(/(\d+):(\d+)\)/, errLine) || [];
if (line && col) {
const srcLine = StringPrototypeSplit(parentSource, '\n')[line - 1];
const srcLine = StringPrototypeSplit(parentSource, '\n', line)[line - 1];
const frame = `${parentPath}:${line}\n${srcLine}\n${StringPrototypeRepeat(' ', col - 1)}^\n`;
setArrowMessage(err, frame);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/modules/esm/module_job.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ class ModuleJob extends ModuleJobBase {
if (!getSourceMapsSupport().enabled &&
StringPrototypeIncludes(e.message,
' does not provide an export named')) {
const splitStack = StringPrototypeSplit(e.stack, '\n');
const splitStack = StringPrototypeSplit(e.stack, '\n', 2);
const parentFileUrl = RegExpPrototypeSymbolReplace(
/:\d+$/,
splitStack[0],
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/repl/await.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ function processTopLevelAwait(src) {
return null;
const line = e.loc.line;
const column = line === 1 ? e.loc.column - wrapPrefix.length : e.loc.column;
let message = '\n' + StringPrototypeSplit(src, '\n')[line - 1] + '\n' +
let message = '\n' + StringPrototypeSplit(src, '\n', line)[line - 1] + '\n' +
StringPrototypeRepeat(' ', column) +
'^\n\n' + RegExpPrototypeSymbolReplace(/ \([^)]+\)/, e.message, '');
// V8 unexpected token errors include the token string.
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/source_map/source_map_cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ function sourceMapFromFile(mapURL) {
// data:[<mediatype>][;base64],<data> see:
// https://tools.ietf.org/html/rfc2397#section-2
function sourceMapFromDataUrl(sourceURL, url) {
const { 0: format, 1: data } = StringPrototypeSplit(url, ',');
const { 0: format, 1: data } = StringPrototypeSplit(url, ',', 2);
const splitFormat = StringPrototypeSplit(format, ';');
const contentType = splitFormat[0];
const base64 = splitFormat[splitFormat.length - 1] === 'base64';
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/test_runner/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ function parseCommandLine() {
);
}

const indexAndTotal = StringPrototypeSplit(shardOption, '/');
const indexAndTotal = StringPrototypeSplit(shardOption, '/', 2);
shard = {
__proto__: null,
index: NumberParseInt(indexAndTotal[0], 10),
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/tty.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ function getColorDepth(env = process.env) {
// Lazy load for startup performance.
if (OSRelease === undefined) {
const { release } = require('os');
OSRelease = StringPrototypeSplit(release(), '.');
OSRelease = StringPrototypeSplit(release(), '.', 3);
}
// Windows 10 build 10586 is the first Windows release that supports 256
// colors. Windows 10 build 14931 is the first release that supports
Expand Down
1 change: 1 addition & 0 deletions lib/internal/util/debuglog.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ function formatTime(ms) {
({ 0: seconds, 1: ms } = StringPrototypeSplit(
NumberPrototypeToFixed(seconds, 3),
'.',
2,
));
const res = hours !== 0 ? `${hours}:${pad(minutes)}` : minutes;
return `${res}:${pad(seconds)}.${ms} (${hours !== 0 ? 'h:m' : ''}m:ss.mmm)`;
Expand Down
2 changes: 1 addition & 1 deletion lib/internal/worker/js_transferable.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function setup() {
// from .postMessage() calls. The format of `deserializeInfo` is generally
// 'module:Constructor', e.g. 'internal/fs/promises:FileHandle'.
setDeserializerCreateObjectFunction((deserializeInfo) => {
const { 0: module, 1: ctor } = StringPrototypeSplit(deserializeInfo, ':');
const { 0: module, 1: ctor } = StringPrototypeSplit(deserializeInfo, ':', 2);
const Ctor = require(module)[ctor];
if (typeof Ctor !== 'function' ||
typeof Ctor.prototype[messaging_deserialize_symbol] !== 'function') {
Expand Down
2 changes: 1 addition & 1 deletion lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ function check(hostParts, pattern, wildcards) {

const hostSubdomain = hostParts[0];
const patternSubdomain = patternParts[0];
const patternSubdomainParts = patternSubdomain.split('*');
const patternSubdomainParts = patternSubdomain.split('*', 3);

// Short-circuit when the subdomain does not contain a wildcard.
// RFC 6125 does not allow wildcard substitution for components
Expand Down
Loading