Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJordan Harband <ljharb@gmail.com>2022-09-22 17:22:18 +0300
committerJuan José Arboleda <soyjuanarbol@gmail.com>2022-10-11 22:45:27 +0300
commita6a655de3563bb41f1fabfcf16ab479007c07a0a (patch)
tree844f2d9b4679906bfc97966b1b7869d9877c652e /lib
parent6758c63eba9c496c2e641bffd12a169718982da6 (diff)
util: increase robustness with primordials
PR-URL: https://github.com/nodejs/node/pull/41212 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/internal/util/inspect.js229
1 files changed, 131 insertions, 98 deletions
diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js
index ca98d2f0937..9e307ccf96e 100644
--- a/lib/internal/util/inspect.js
+++ b/lib/internal/util/inspect.js
@@ -5,9 +5,15 @@ const {
ArrayIsArray,
ArrayPrototypeFilter,
ArrayPrototypeForEach,
+ ArrayPrototypeIncludes,
+ ArrayPrototypeIndexOf,
+ ArrayPrototypeJoin,
+ ArrayPrototypeMap,
ArrayPrototypePop,
ArrayPrototypePush,
ArrayPrototypePushApply,
+ ArrayPrototypeSlice,
+ ArrayPrototypeSplice,
ArrayPrototypeSort,
ArrayPrototypeUnshift,
BigIntPrototypeValueOf,
@@ -16,6 +22,7 @@ const {
DatePrototypeToISOString,
DatePrototypeToString,
ErrorPrototypeToString,
+ FunctionPrototypeBind,
FunctionPrototypeCall,
FunctionPrototypeToString,
JSONStringify,
@@ -32,6 +39,7 @@ const {
NumberIsNaN,
NumberParseFloat,
NumberParseInt,
+ NumberPrototypeToString,
NumberPrototypeValueOf,
Object,
ObjectAssign,
@@ -47,10 +55,12 @@ const {
ObjectPrototypePropertyIsEnumerable,
ObjectSeal,
ObjectSetPrototypeOf,
+ ReflectApply,
ReflectOwnKeys,
RegExp,
RegExpPrototypeExec,
RegExpPrototypeSymbolReplace,
+ RegExpPrototypeSymbolSplit,
RegExpPrototypeToString,
SafeStringIterator,
SafeMap,
@@ -61,12 +71,17 @@ const {
StringPrototypeCharCodeAt,
StringPrototypeCodePointAt,
StringPrototypeIncludes,
+ StringPrototypeIndexOf,
+ StringPrototypeLastIndexOf,
StringPrototypeNormalize,
StringPrototypePadEnd,
StringPrototypePadStart,
StringPrototypeRepeat,
+ StringPrototypeReplaceAll,
StringPrototypeSlice,
StringPrototypeSplit,
+ StringPrototypeEndsWith,
+ StringPrototypeStartsWith,
StringPrototypeToLowerCase,
StringPrototypeTrim,
StringPrototypeValueOf,
@@ -367,7 +382,8 @@ ObjectDefineProperty(inspect, 'defaultOptions', {
// reset code as second entry.
const defaultFG = 39;
const defaultBG = 49;
-inspect.colors = ObjectAssign(ObjectCreate(null), {
+inspect.colors = {
+ __proto__: null,
reset: [0, 0],
bold: [1, 22],
dim: [2, 22], // Alias: faint
@@ -413,7 +429,7 @@ inspect.colors = ObjectAssign(ObjectCreate(null), {
bgMagentaBright: [105, defaultBG],
bgCyanBright: [106, defaultBG],
bgWhiteBright: [107, defaultBG],
-});
+};
function defineColorAlias(target, alias) {
ObjectDefineProperty(inspect.colors, alias, {
@@ -472,7 +488,7 @@ function addQuotes(str, quotes) {
function escapeFn(str) {
const charCode = StringPrototypeCharCodeAt(str);
- return meta.length > charCode ? meta[charCode] : `\\u${charCode.toString(16)}`;
+ return meta.length > charCode ? meta[charCode] : `\\u${NumberPrototypeToString(charCode, 16)}`;
}
// Escape control characters, single quotes and the backslash.
@@ -531,7 +547,7 @@ function strEscape(str) {
continue;
}
}
- result += `${StringPrototypeSlice(str, last, i)}\\u${point.toString(16)}`;
+ result += `${StringPrototypeSlice(str, last, i)}\\u${NumberPrototypeToString(point, 16)}`;
last = i + 1;
}
}
@@ -800,7 +816,7 @@ function formatValue(ctx, value, recurseTimes, typedArray) {
if (typeof ret !== 'string') {
return formatValue(ctx, ret, recurseTimes);
}
- return ret.replace(/\n/g, `\n${' '.repeat(ctx.indentationLvl)}`);
+ return StringPrototypeReplaceAll(ret, '\n', `\n${StringPrototypeRepeat(' ', ctx.indentationLvl)}`);
}
}
}
@@ -880,8 +896,8 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
const prefix = getPrefix(constructor, tag, 'Set', `(${size})`);
keys = getKeys(value, ctx.showHidden);
formatter = constructor !== null ?
- formatSet.bind(null, value) :
- formatSet.bind(null, SetPrototypeValues(value));
+ FunctionPrototypeBind(formatSet, null, value) :
+ FunctionPrototypeBind(formatSet, null, SetPrototypeValues(value));
if (size === 0 && keys.length === 0 && protoProps === undefined)
return `${prefix}{}`;
braces = [`${prefix}{`, '}'];
@@ -890,8 +906,8 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
const prefix = getPrefix(constructor, tag, 'Map', `(${size})`);
keys = getKeys(value, ctx.showHidden);
formatter = constructor !== null ?
- formatMap.bind(null, value) :
- formatMap.bind(null, MapPrototypeEntries(value));
+ FunctionPrototypeBind(formatMap, null, value) :
+ FunctionPrototypeBind(formatMap, null, MapPrototypeEntries(value));
if (size === 0 && keys.length === 0 && protoProps === undefined)
return `${prefix}{}`;
braces = [`${prefix}{`, '}'];
@@ -911,18 +927,18 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
return `${braces[0]}]`;
// Special handle the value. The original value is required below. The
// bound function is required to reconstruct missing information.
- formatter = formatTypedArray.bind(null, bound, size);
+ formatter = FunctionPrototypeBind(formatTypedArray, null, bound, size);
extrasType = kArrayExtrasType;
} else if (isMapIterator(value)) {
keys = getKeys(value, ctx.showHidden);
braces = getIteratorBraces('Map', tag);
// Add braces to the formatter parameters.
- formatter = formatIterator.bind(null, braces);
+ formatter = FunctionPrototypeBind(formatIterator, null, braces);
} else if (isSetIterator(value)) {
keys = getKeys(value, ctx.showHidden);
braces = getIteratorBraces('Set', tag);
// Add braces to the formatter parameters.
- formatter = formatIterator.bind(null, braces);
+ formatter = FunctionPrototypeBind(formatIterator, null, braces);
} else {
noIterator = true;
}
@@ -1020,7 +1036,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
}
if (recurseTimes > ctx.depth && ctx.depth !== null) {
- let constructorName = getCtxStyle(value, constructor, tag).slice(0, -1);
+ let constructorName = StringPrototypeSlice(getCtxStyle(value, constructor, tag), 0, -1);
if (constructor !== null)
constructorName = `[${constructorName}]`;
return ctx.stylize(constructorName, 'special');
@@ -1034,14 +1050,16 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
try {
output = formatter(ctx, value, recurseTimes);
for (i = 0; i < keys.length; i++) {
- output.push(
- formatProperty(ctx, value, recurseTimes, keys[i], extrasType));
+ ArrayPrototypePush(
+ output,
+ formatProperty(ctx, value, recurseTimes, keys[i], extrasType),
+ );
}
if (protoProps !== undefined) {
- output.push(...protoProps);
+ ArrayPrototypePushApply(output, protoProps);
}
} catch (err) {
- const constructorName = getCtxStyle(value, constructor, tag).slice(0, -1);
+ const constructorName = StringPrototypeSlice(getCtxStyle(value, constructor, tag), 0, -1);
return handleMaxCallStackSize(ctx, err, constructorName, indentationLvl);
}
if (ctx.circular !== undefined) {
@@ -1061,10 +1079,11 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
if (ctx.sorted) {
const comparator = ctx.sorted === true ? undefined : ctx.sorted;
if (extrasType === kObjectType) {
- output = output.sort(comparator);
+ ArrayPrototypeSort(output, comparator);
} else if (keys.length > 1) {
- const sorted = output.slice(output.length - keys.length).sort(comparator);
- output.splice(output.length - keys.length, keys.length, ...sorted);
+ const sorted = ArrayPrototypeSort(ArrayPrototypeSlice(output, output.length - keys.length), comparator);
+ ArrayPrototypeUnshift(sorted, output, output.length - keys.length, keys.length);
+ ReflectApply(ArrayPrototypeSplice, null, sorted);
}
}
@@ -1158,13 +1177,14 @@ function getClassBase(value, constructor, tag) {
function getFunctionBase(value, constructor, tag) {
const stringified = FunctionPrototypeToString(value);
- if (stringified.startsWith('class') && stringified.endsWith('}')) {
- const slice = stringified.slice(5, -1);
- const bracketIndex = slice.indexOf('{');
+ if (StringPrototypeStartsWith(stringified, 'class') && StringPrototypeEndsWith(stringified, '}')) {
+ const slice = StringPrototypeSlice(stringified, 5, -1);
+ const bracketIndex = StringPrototypeIndexOf(slice, '{');
if (bracketIndex !== -1 &&
- (!slice.slice(0, bracketIndex).includes('(') ||
- // Slow path to guarantee that it's indeed a class.
- classRegExp.test(slice.replace(stripCommentsRegExp)))) {
+ (!StringPrototypeIncludes(StringPrototypeSlice(slice, 0, bracketIndex), '(') ||
+ // Slow path to guarantee that it's indeed a class.
+ RegExpPrototypeExec(classRegExp, RegExpPrototypeSymbolReplace(stripCommentsRegExp, slice)) !== null)
+ ) {
return getClassBase(value, constructor, tag);
}
}
@@ -1222,14 +1242,14 @@ function getStackString(error) {
}
function getStackFrames(ctx, err, stack) {
- const frames = stack.split('\n');
+ const frames = StringPrototypeSplit(stack, '\n');
// Remove stack frames identical to frames in cause.
if (err.cause && isError(err.cause)) {
const causeStack = getStackString(err.cause);
- const causeStackStart = causeStack.indexOf('\n at');
+ const causeStackStart = StringPrototypeIndexOf(causeStack, '\n at');
if (causeStackStart !== -1) {
- const causeFrames = causeStack.slice(causeStackStart + 1).split('\n');
+ const causeFrames = StringPrototypeSplit(StringPrototypeSlice(causeStack, causeStackStart + 1), '\n');
const { len, offset } = identicalSequenceRange(frames, causeFrames);
if (len > 0) {
const skipped = len - 2;
@@ -1247,27 +1267,27 @@ function improveStack(stack, constructor, name, tag) {
let len = name.length;
if (constructor === null ||
- (name.endsWith('Error') &&
- stack.startsWith(name) &&
+ (StringPrototypeEndsWith(name, 'Error') &&
+ StringPrototypeStartsWith(stack, name) &&
(stack.length === len || stack[len] === ':' || stack[len] === '\n'))) {
let fallback = 'Error';
if (constructor === null) {
- const start = stack.match(/^([A-Z][a-z_ A-Z0-9[\]()-]+)(?::|\n {4}at)/) ||
- stack.match(/^([a-z_A-Z0-9-]*Error)$/);
+ const start = RegExpPrototypeExec(/^([A-Z][a-z_ A-Z0-9[\]()-]+)(?::|\n {4}at)/, stack) ||
+ RegExpPrototypeExec(/^([a-z_A-Z0-9-]*Error)$/, stack);
fallback = (start && start[1]) || '';
len = fallback.length;
fallback = fallback || 'Error';
}
- const prefix = getPrefix(constructor, tag, fallback).slice(0, -1);
+ const prefix = StringPrototypeSlice(getPrefix(constructor, tag, fallback), 0, -1);
if (name !== prefix) {
- if (prefix.includes(name)) {
+ if (StringPrototypeIncludes(prefix, name)) {
if (len === 0) {
stack = `${prefix}: ${stack}`;
} else {
- stack = `${prefix}${stack.slice(len)}`;
+ stack = `${prefix}${StringPrototypeSlice(stack, len)}`;
}
} else {
- stack = `${prefix} [${name}]${stack.slice(len)}`;
+ stack = `${prefix} [${name}]${StringPrototypeSlice(stack, len)}`;
}
}
}
@@ -1277,10 +1297,10 @@ function improveStack(stack, constructor, name, tag) {
function removeDuplicateErrorKeys(ctx, keys, err, stack) {
if (!ctx.showHidden && keys.length !== 0) {
for (const name of ['name', 'message', 'stack']) {
- const index = keys.indexOf(name);
+ const index = ArrayPrototypeIndexOf(keys, name);
// Only hide the property in case it's part of the original stack
- if (index !== -1 && stack.includes(err[name])) {
- keys.splice(index, 1);
+ if (index !== -1 && StringPrototypeIncludes(stack, err[name])) {
+ ArrayPrototypeSplice(keys, index, 1);
}
}
}
@@ -1292,33 +1312,33 @@ function markNodeModules(ctx, line) {
let pos = 0;
while ((nodeModule = nodeModulesRegExp.exec(line)) !== null) {
// '/node_modules/'.length === 14
- tempLine += line.slice(pos, nodeModule.index + 14);
+ tempLine += StringPrototypeSlice(line, pos, nodeModule.index + 14);
tempLine += ctx.stylize(nodeModule[1], 'module');
pos = nodeModule.index + nodeModule[0].length;
}
if (pos !== 0) {
- line = tempLine + line.slice(pos);
+ line = tempLine + StringPrototypeSlice(line, pos);
}
return line;
}
function markCwd(ctx, line, workingDirectory) {
- let cwdStartPos = line.indexOf(workingDirectory);
+ let cwdStartPos = StringPrototypeIndexOf(line, workingDirectory);
let tempLine = '';
let cwdLength = workingDirectory.length;
if (cwdStartPos !== -1) {
- if (line.slice(cwdStartPos - 7, cwdStartPos) === 'file://') {
+ if (StringPrototypeSlice(line, cwdStartPos - 7, cwdStartPos) === 'file://') {
cwdLength += 7;
cwdStartPos -= 7;
}
const start = line[cwdStartPos - 1] === '(' ? cwdStartPos - 1 : cwdStartPos;
- const end = start !== cwdStartPos && line.endsWith(')') ? -1 : line.length;
+ const end = start !== cwdStartPos && StringPrototypeEndsWith(line, ')') ? -1 : line.length;
const workingDirectoryEndPos = cwdStartPos + cwdLength + 1;
- const cwdSlice = line.slice(start, workingDirectoryEndPos);
+ const cwdSlice = StringPrototypeSlice(line, start, workingDirectoryEndPos);
- tempLine += line.slice(0, start);
+ tempLine += StringPrototypeSlice(line, 0, start);
tempLine += ctx.stylize(cwdSlice, 'undefined');
- tempLine += line.slice(workingDirectoryEndPos, end);
+ tempLine += StringPrototypeSlice(line, workingDirectoryEndPos, end);
if (end === -1) {
tempLine += ctx.stylize(')', 'undefined');
}
@@ -1345,36 +1365,36 @@ function formatError(err, constructor, tag, ctx, keys) {
removeDuplicateErrorKeys(ctx, keys, err, stack);
if ('cause' in err &&
- (keys.length === 0 || !keys.includes('cause'))) {
- keys.push('cause');
+ (keys.length === 0 || !ArrayPrototypeIncludes(keys, 'cause'))) {
+ ArrayPrototypePush(keys, 'cause');
}
// Print errors aggregated into AggregateError
if (ArrayIsArray(err.errors) &&
- (keys.length === 0 || !keys.includes('errors'))) {
- keys.push('errors');
+ (keys.length === 0 || !ArrayPrototypeIncludes(keys, 'errors'))) {
+ ArrayPrototypePush(keys, 'errors');
}
stack = improveStack(stack, constructor, name, tag);
// Ignore the error message if it's contained in the stack.
- let pos = (err.message && stack.indexOf(err.message)) || -1;
+ let pos = (err.message && StringPrototypeIndexOf(stack, err.message)) || -1;
if (pos !== -1)
pos += err.message.length;
// Wrap the error in brackets in case it has no stack trace.
- const stackStart = stack.indexOf('\n at', pos);
+ const stackStart = StringPrototypeIndexOf(stack, '\n at', pos);
if (stackStart === -1) {
stack = `[${stack}]`;
} else {
- let newStack = stack.slice(0, stackStart);
- const stackFramePart = stack.slice(stackStart + 1);
+ let newStack = StringPrototypeSlice(stack, 0, stackStart);
+ const stackFramePart = StringPrototypeSlice(stack, stackStart + 1);
const lines = getStackFrames(ctx, err, stackFramePart);
if (ctx.colors) {
// Highlight userland code and node modules.
const workingDirectory = safeGetCWD();
let esmWorkingDirectory;
for (let line of lines) {
- const core = line.match(coreModuleRegExp);
+ const core = RegExpPrototypeExec(coreModuleRegExp, line);
if (core !== null && NativeModule.exists(core[1])) {
newStack += `\n${ctx.stylize(line, 'undefined')}`;
} else {
@@ -1394,14 +1414,14 @@ function formatError(err, constructor, tag, ctx, keys) {
}
}
} else {
- newStack += `\n${lines.join('\n')}`;
+ newStack += `\n${ArrayPrototypeJoin(lines, '\n')}`;
}
stack = newStack;
}
// The message and the stack have to be indented as well!
if (ctx.indentationLvl !== 0) {
- const indentation = ' '.repeat(ctx.indentationLvl);
- stack = stack.replace(/\n/g, `\n${indentation}`);
+ const indentation = StringPrototypeRepeat(' ', ctx.indentationLvl);
+ stack = StringPrototypeReplaceAll(stack, '\n', `\n${indentation}`);
}
return stack;
}
@@ -1533,24 +1553,24 @@ function handleMaxCallStackSize(ctx, err, constructorName, indentationLvl) {
function addNumericSeparator(integerString) {
let result = '';
let i = integerString.length;
- const start = integerString.startsWith('-') ? 1 : 0;
+ const start = StringPrototypeStartsWith(integerString, '-') ? 1 : 0;
for (; i >= start + 4; i -= 3) {
- result = `_${integerString.slice(i - 3, i)}${result}`;
+ result = `_${StringPrototypeSlice(integerString, i - 3, i)}${result}`;
}
return i === integerString.length ?
integerString :
- `${integerString.slice(0, i)}${result}`;
+ `${StringPrototypeSlice(integerString, 0, i)}${result}`;
}
function addNumericSeparatorEnd(integerString) {
let result = '';
let i = 0;
for (; i < integerString.length - 3; i += 3) {
- result += `${integerString.slice(i, i + 3)}_`;
+ result += `${StringPrototypeSlice(integerString, i, i + 3)}_`;
}
return i === 0 ?
integerString :
- `${result}${integerString.slice(i)}`;
+ `${result}${StringPrototypeSlice(integerString, i)}`;
}
const remainingText = (remaining) => `... ${remaining} more item${remaining > 1 ? 's' : ''}`;
@@ -1566,7 +1586,7 @@ function formatNumber(fn, number, numericSeparator) {
const integer = MathTrunc(number);
const string = String(integer);
if (integer === number) {
- if (!NumberIsFinite(number) || string.includes('e')) {
+ if (!NumberIsFinite(number) || StringPrototypeIncludes(string, 'e')) {
return fn(string, 'number');
}
return fn(`${addNumericSeparator(string)}`, 'number');
@@ -1577,7 +1597,9 @@ function formatNumber(fn, number, numericSeparator) {
return fn(`${
addNumericSeparator(string)
}.${
- addNumericSeparatorEnd(String(number).slice(string.length + 1))
+ addNumericSeparatorEnd(
+ StringPrototypeSlice(String(number), string.length + 1)
+ )
}`, 'number');
}
@@ -1594,7 +1616,7 @@ function formatPrimitive(fn, value, ctx) {
let trailer = '';
if (value.length > ctx.maxStringLength) {
const remaining = value.length - ctx.maxStringLength;
- value = value.slice(0, ctx.maxStringLength);
+ value = StringPrototypeSlice(value, 0, ctx.maxStringLength);
trailer = `... ${remaining} more character${remaining > 1 ? 's' : ''}`;
}
if (ctx.compact !== true &&
@@ -1603,10 +1625,13 @@ function formatPrimitive(fn, value, ctx) {
// performance implications.
value.length > kMinLineLength &&
value.length > ctx.breakLength - ctx.indentationLvl - 4) {
- return value
- .split(/(?<=\n)/)
- .map((line) => fn(strEscape(line), 'string'))
- .join(` +\n${' '.repeat(ctx.indentationLvl + 2)}`) + trailer;
+ return ArrayPrototypeJoin(
+ ArrayPrototypeMap(
+ RegExpPrototypeSymbolSplit(/(?<=\n)/, value),
+ (line) => fn(strEscape(line), 'string'),
+ ),
+ ` +\n${StringPrototypeRepeat(' ', ctx.indentationLvl + 2)}`,
+ ) + trailer;
}
return fn(strEscape(value), 'string') + trailer;
}
@@ -1635,10 +1660,10 @@ function formatNamespaceObject(keys, ctx, value, recurseTimes) {
// this aligned, even though this is a hacky way of dealing with this.
const tmp = { [keys[i]]: '' };
output[i] = formatProperty(ctx, tmp, recurseTimes, keys[i], kObjectType);
- const pos = output[i].lastIndexOf(' ');
+ const pos = StringPrototypeLastIndexOf(output[i], ' ');
// We have to find the last whitespace and have to replace that value as
// it will be visualized as a regular string.
- output[i] = output[i].slice(0, pos + 1) +
+ output[i] = StringPrototypeSlice(output[i], 0, pos + 1) +
ctx.stylize('<uninitialized>', 'special');
}
}
@@ -1659,19 +1684,19 @@ function formatSpecialArray(ctx, value, recurseTimes, maxLength, output, i) {
break;
}
if (`${index}` !== key) {
- if (!numberRegExp.test(key)) {
+ if (RegExpPrototypeExec(numberRegExp, key) === null) {
break;
}
const emptyItems = tmp - index;
const ending = emptyItems > 1 ? 's' : '';
const message = `<${emptyItems} empty item${ending}>`;
- output.push(ctx.stylize(message, 'undefined'));
+ ArrayPrototypePush(output, ctx.stylize(message, 'undefined'));
index = tmp;
if (output.length === maxLength) {
break;
}
}
- output.push(formatProperty(ctx, value, recurseTimes, key, kArrayType));
+ ArrayPrototypePush(output, formatProperty(ctx, value, recurseTimes, key, kArrayType));
index++;
}
const remaining = value.length - index;
@@ -1679,10 +1704,10 @@ function formatSpecialArray(ctx, value, recurseTimes, maxLength, output, i) {
if (remaining > 0) {
const ending = remaining > 1 ? 's' : '';
const message = `<${remaining} empty item${ending}>`;
- output.push(ctx.stylize(message, 'undefined'));
+ ArrayPrototypePush(output, ctx.stylize(message, 'undefined'));
}
} else if (remaining > 0) {
- output.push(remainingText(remaining));
+ ArrayPrototypePush(output, remainingText(remaining));
}
return output;
}
@@ -1699,7 +1724,8 @@ function formatArrayBuffer(ctx, value) {
let str = StringPrototypeTrim(RegExpPrototypeSymbolReplace(
/(.{2})/g,
hexSlice(buffer, 0, MathMin(ctx.maxArrayLength, buffer.length)),
- '$1 '));
+ '$1 ',
+ ));
const remaining = buffer.length - ctx.maxArrayLength;
if (remaining > 0)
str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`;
@@ -1717,10 +1743,11 @@ function formatArray(ctx, value, recurseTimes) {
if (!ObjectPrototypeHasOwnProperty(value, i)) {
return formatSpecialArray(ctx, value, recurseTimes, len, output, i);
}
- output.push(formatProperty(ctx, value, recurseTimes, i, kArrayType));
+ ArrayPrototypePush(output, formatProperty(ctx, value, recurseTimes, i, kArrayType));
+ }
+ if (remaining > 0) {
+ ArrayPrototypePush(output, remainingText(remaining));
}
- if (remaining > 0)
- output.push(remainingText(remaining));
return output;
}
@@ -1784,8 +1811,9 @@ function formatMap(value, ctx, ignored, recurseTimes) {
let i = 0;
for (const { 0: k, 1: v } of value) {
if (i >= maxLength) break;
- output.push(
- `${formatValue(ctx, k, recurseTimes)} => ${formatValue(ctx, v, recurseTimes)}`
+ ArrayPrototypePush(
+ output,
+ `${formatValue(ctx, k, recurseTimes)} => ${formatValue(ctx, v, recurseTimes)}`,
);
i++;
}
@@ -1824,7 +1852,7 @@ function formatMapIterInner(ctx, recurseTimes, entries, state) {
const len = entries.length / 2;
const remaining = len - maxArrayLength;
const maxLength = MathMin(maxArrayLength, len);
- let output = new Array(maxLength);
+ const output = new Array(maxLength);
let i = 0;
ctx.indentationLvl += 2;
if (state === kWeak) {
@@ -1837,7 +1865,7 @@ function formatMapIterInner(ctx, recurseTimes, entries, state) {
// retrieved ones exist, we can not reliably return the same output) if the
// output is not sorted anyway.
if (!ctx.sorted)
- output = output.sort();
+ ArrayPrototypeSort(output);
} else {
for (; i < maxLength; i++) {
const pos = i * 2;
@@ -1851,7 +1879,7 @@ function formatMapIterInner(ctx, recurseTimes, entries, state) {
}
ctx.indentationLvl -= 2;
if (remaining > 0) {
- output.push(remainingText(remaining));
+ ArrayPrototypePush(output, remainingText(remaining));
}
return output;
}
@@ -1874,7 +1902,7 @@ function formatIterator(braces, ctx, value, recurseTimes) {
const { 0: entries, 1: isKeyValue } = previewEntries(value, true);
if (isKeyValue) {
// Mark entry iterators as such.
- braces[0] = braces[0].replace(/ Iterator] {$/, ' Entries] {');
+ braces[0] = RegExpPrototypeSymbolReplace(/ Iterator] {$/, braces[0], ' Entries] {');
return formatMapIterInner(ctx, recurseTimes, entries, kMapEntries);
}
@@ -1910,7 +1938,7 @@ function formatProperty(ctx, value, recurseTimes, key, type, desc,
ctx.indentationLvl += diff;
str = formatValue(ctx, desc.value, recurseTimes);
if (diff === 3 && ctx.breakLength < getStringWidth(str, ctx.colors)) {
- extra = `\n${' '.repeat(ctx.indentationLvl)}`;
+ extra = `\n${StringPrototypeRepeat(' ', ctx.indentationLvl)}`;
}
ctx.indentationLvl -= diff;
} else if (desc.get !== undefined) {
@@ -1958,7 +1986,10 @@ function formatProperty(ctx, value, recurseTimes, key, type, desc,
name = "['__proto__']";
} else if (desc.enumerable === false) {
const tmp = RegExpPrototypeSymbolReplace(
- strEscapeSequencesReplacer, key, escapeFn);
+ strEscapeSequencesReplacer,
+ key,
+ escapeFn,
+ );
name = `[${tmp}]`;
} else if (RegExpPrototypeExec(keyStrRegExp, key) !== null) {
name = ctx.stylize(key, 'name');
@@ -2027,7 +2058,7 @@ function reduceToSingleString(
braces[0].length + base.length + 10;
if (isBelowBreakLength(ctx, output, start, base)) {
const joinedOutput = join(output, ', ');
- if (!joinedOutput.includes('\n')) {
+ if (!StringPrototypeIncludes(joinedOutput, '\n')) {
return `${base ? `${base} ` : ''}${braces[0]} ${joinedOutput}` +
` ${braces[1]}`;
}
@@ -2090,8 +2121,7 @@ function hasBuiltInToString(value) {
builtInObjects.has(descriptor.value.name);
}
-const firstErrorLine = (error) =>
- StringPrototypeSplit(error.message, '\n', 1)[0];
+const firstErrorLine = (error) => StringPrototypeSplit(error.message, '\n', 1)[0];
let CIRCULAR_ERROR_MESSAGE;
function tryStringify(arg) {
try {
@@ -2100,7 +2130,9 @@ function tryStringify(arg) {
// Populate the circular error message lazily
if (!CIRCULAR_ERROR_MESSAGE) {
try {
- const a = {}; a.a = a; JSONStringify(a);
+ const a = {};
+ a.a = a;
+ JSONStringify(a);
} catch (circularError) {
CIRCULAR_ERROR_MESSAGE = firstErrorLine(circularError);
}
@@ -2274,14 +2306,15 @@ if (internalBinding('config').hasIntl) {
getStringWidth = function getStringWidth(str, removeControlChars = true) {
let width = 0;
- if (removeControlChars)
+ if (removeControlChars) {
str = stripVTControlCharacters(str);
+ }
for (let i = 0; i < str.length; i++) {
// Try to avoid calling into C++ by first handling the ASCII portion of
// the string. If it is fully ASCII, we skip the C++ part.
const code = str.charCodeAt(i);
if (code >= 127) {
- width += icu.getStringWidth(str.slice(i).normalize('NFC'));
+ width += icu.getStringWidth(StringPrototypeNormalize(StringPrototypeSlice(str, i), 'NFC'));
break;
}
width += code >= 32 ? 1 : 0;
@@ -2371,7 +2404,7 @@ if (internalBinding('config').hasIntl) {
function stripVTControlCharacters(str) {
validateString(str, 'str');
- return str.replace(ansi, '');
+ return RegExpPrototypeSymbolReplace(ansi, str, '');
}
module.exports = {