util: prevent tampering with internals in inspect() · nodejs/node@5672ab7 (original) (raw)

`@@ -150,6 +150,16 @@ const meta = [

`

150

150

`'', '', '', '', '', '', '', '\\'

`

151

151

`];

`

152

152

``

``

153

`+

function getUserOptions(ctx) {

`

``

154

`+

const obj = { stylize: ctx.stylize };

`

``

155

`+

for (const key of Object.keys(inspectDefaultOptions)) {

`

``

156

`+

obj[key] = ctx[key];

`

``

157

`+

}

`

``

158

`+

if (ctx.userOptions === undefined)

`

``

159

`+

return obj;

`

``

160

`+

return { ...obj, ...ctx.userOptions };

`

``

161

`+

}

`

``

162

+

153

163

`/**

`

154

164

` * Echos the value of any input. Tries to print the value out

`

155

165

` * in the best way possible given the different types.

`

`@@ -192,8 +202,16 @@ function inspect(value, opts) {

`

192

202

`ctx.showHidden = opts;

`

193

203

`} else if (opts) {

`

194

204

`const optKeys = Object.keys(opts);

`

195

``

`-

for (var i = 0; i < optKeys.length; i++) {

`

196

``

`-

ctx[optKeys[i]] = opts[optKeys[i]];

`

``

205

`+

for (const key of optKeys) {

`

``

206

`+

// TODO(BridgeAR): Find a solution what to do about stylize. Either make

`

``

207

`+

// this function public or add a new API with a similar or better

`

``

208

`+

// functionality.

`

``

209

`+

if (hasOwnProperty(inspectDefaultOptions, key) || key === 'stylize') {

`

``

210

`+

ctx[key] = opts[key];

`

``

211

`+

} else if (ctx.userOptions === undefined) {

`

``

212

`+

// This is required to pass through the actual user input.

`

``

213

`+

ctx.userOptions = opts;

`

``

214

`+

}

`

197

215

`}

`

198

216

`}

`

199

217

`}

`

`@@ -522,14 +540,10 @@ function formatValue(ctx, value, recurseTimes, typedArray) {

`

522

540

`maybeCustom !== inspect &&

`

523

541

`// Also filter out any prototype objects using the circular check.

`

524

542

`!(value.constructor && value.constructor.prototype === value)) {

`

525

``

`-

// Remove some internal properties from the options before passing it

`

526

``

`-

// through to the user function. This also prevents option manipulation.

`

527

``

`-

// eslint-disable-next-line no-unused-vars

`

528

``

`-

const { budget, seen, indentationLvl, ...plainCtx } = ctx;

`

529

543

`// This makes sure the recurseTimes are reported as before while using

`

530

544

`// a counter internally.

`

531

545

`const depth = ctx.depth === null ? null : ctx.depth - recurseTimes;

`

532

``

`-

const ret = maybeCustom.call(context, depth, plainCtx);

`

``

546

`+

const ret = maybeCustom.call(context, depth, getUserOptions(ctx));

`

533

547

`` // If the custom inspection method returned this, don't go into

``

534

548

`// infinite recursion.

`

535

549

`if (ret !== context) {

`