util: escaping object keys in util.inspect()

PR-URL: https://github.com/nodejs/node/pull/16986
Fixes: https://github.com/nodejs/node/issues/16979
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
This commit is contained in:
buji 2017-11-13 19:44:16 +08:00 committed by Anna Henningsen
parent 95d9a58cbc
commit 71ee0d9a40
No known key found for this signature in database
GPG Key ID: 9C63F3A6CD2AD8F9
2 changed files with 11 additions and 35 deletions

View File

@ -81,9 +81,7 @@ var Debug;
/* eslint-disable */
const strEscapeSequencesRegExp = /[\x00-\x1f\x27\x5c]/;
const keyEscapeSequencesRegExp = /[\x00-\x1f\x27]/;
const strEscapeSequencesReplacer = /[\x00-\x1f\x27\x5c]/g;
const keyEscapeSequencesReplacer = /[\x00-\x1f\x27]/g;
/* eslint-enable */
const keyStrRegExp = /^[a-zA-Z_][a-zA-Z_0-9]*$/;
const colorRegExp = /\u001b\[\d\d?m/g;
@ -137,34 +135,6 @@ function strEscape(str) {
return `'${result}'`;
}
// Escape control characters and single quotes.
// Note: for performance reasons this is not combined with strEscape
function keyEscape(str) {
if (str.length < 5000 && !keyEscapeSequencesRegExp.test(str))
return `'${str}'`;
if (str.length > 100)
return `'${str.replace(keyEscapeSequencesReplacer, escapeFn)}'`;
var result = '';
var last = 0;
for (var i = 0; i < str.length; i++) {
const point = str.charCodeAt(i);
if (point === 39 || point < 32) {
if (last === i) {
result += meta[point];
} else {
result += `${str.slice(last, i)}${meta[point]}`;
}
last = i + 1;
}
}
if (last === 0) {
result = str;
} else if (last !== i) {
result += str.slice(last);
}
return `'${result}'`;
}
function tryStringify(arg) {
try {
return JSON.stringify(arg);
@ -868,7 +838,7 @@ function formatProperty(ctx, value, recurseTimes, key, array) {
} else if (keyStrRegExp.test(key)) {
name = ctx.stylize(key, 'name');
} else {
name = ctx.stylize(keyEscape(key), 'string');
name = ctx.stylize(strEscape(key), 'string');
}
return `${name}: ${str}`;

View File

@ -566,25 +566,31 @@ assert.doesNotThrow(() => {
assert.strictEqual(util.inspect(x).includes('inspect'), true);
}
// util.inspect should not display the escaped value of a key.
// util.inspect should display the escaped value of a key.
{
const w = {
'\\': 1,
'\\\\': 2,
'\\\\\\': 3,
'\\\\\\\\': 4,
'\n': 5,
'\r': 6
};
const y = ['a', 'b', 'c'];
y['\\\\\\'] = 'd';
y['\\\\'] = 'd';
y['\n'] = 'e';
y['\r'] = 'f';
assert.strictEqual(
util.inspect(w),
'{ \'\\\': 1, \'\\\\\': 2, \'\\\\\\\': 3, \'\\\\\\\\\': 4 }'
'{ \'\\\\\': 1, \'\\\\\\\\\': 2, \'\\\\\\\\\\\\\': 3, ' +
'\'\\\\\\\\\\\\\\\\\': 4, \'\\n\': 5, \'\\r\': 6 }'
);
assert.strictEqual(
util.inspect(y),
'[ \'a\', \'b\', \'c\', \'\\\\\\\': \'d\' ]'
'[ \'a\', \'b\', \'c\', \'\\\\\\\\\': \'d\', ' +
'\'\\n\': \'e\', \'\\r\': \'f\' ]'
);
}