Skip to content

Commit 3b2895d

Browse files
committed
util: inspect: avoid a crash on a DataView with a detached buffer
1 parent da5f7ac commit 3b2895d

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

lib/internal/util/inspect.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
987987
noIterator = true;
988988
}
989989
}
990+
let isDV;
990991
if (noIterator) {
991992
keys = getKeys(value, ctx.showHidden);
992993
braces = ['{', '}'];
@@ -1046,6 +1047,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
10461047
braces[0] = `${prefix}{`;
10471048
ArrayPrototypeUnshift(keys, 'byteLength');
10481049
} else if (isDataView(value)) {
1050+
isDV = true;
10491051
braces[0] = `${getPrefix(constructor, tag, 'DataView')}{`;
10501052
// .buffer goes last, it's not a primitive like the others.
10511053
ArrayPrototypeUnshift(keys, 'byteLength', 'byteOffset', 'buffer');
@@ -1099,6 +1101,20 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
10991101
try {
11001102
output = formatter(ctx, value, recurseTimes);
11011103
for (i = 0; i < keys.length; i++) {
1104+
isDV ??= isDataView(value);
1105+
if (
1106+
isDV && (keys[i] === 'byteLength' || keys[i] === 'byteOffset')
1107+
) {
1108+
try {
1109+
new Uint8Array(value.buffer);
1110+
} catch {
1111+
ArrayPrototypePush(
1112+
output,
1113+
formatValue(ctx, value.buffer.byteLength),
1114+
);
1115+
continue;
1116+
}
1117+
}
11021118
ArrayPrototypePush(
11031119
output,
11041120
formatProperty(ctx, value, recurseTimes, keys[i], extrasType),
@@ -1994,8 +2010,7 @@ function formatProperty(ctx, value, recurseTimes, key, type, desc,
19942010
original = value) {
19952011
let name, str;
19962012
let extra = ' ';
1997-
desc ||= ObjectGetOwnPropertyDescriptor(value, key) ||
1998-
{ value: value[key], enumerable: true };
2013+
desc ||= ObjectGetOwnPropertyDescriptor(value, key) || { value: value[key], enumerable: true };
19992014
if (desc.value !== undefined) {
20002015
const diff = (ctx.compact !== true || type !== kObjectType) ? 2 : 3;
20012016
ctx.indentationLvl += diff;

test/parallel/test-util-inspect.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,20 @@ assert.doesNotMatch(
206206

207207
{
208208
const ab = new ArrayBuffer(42);
209+
const dv = new DataView(ab);
210+
209211
assert.strictEqual(ab.byteLength, 42);
210212
new MessageChannel().port1.postMessage(ab, [ ab ]);
211213
assert.strictEqual(ab.byteLength, 0);
212-
assert.strictEqual(util.inspect(ab),
213-
'ArrayBuffer { (detached), byteLength: 0 }');
214+
assert.strictEqual(
215+
util.inspect(ab),
216+
'ArrayBuffer { (detached), byteLength: 0 }',
217+
);
218+
219+
assert.strictEqual(
220+
util.inspect(dv),
221+
'DataView { 0, 0, buffer: ArrayBuffer { (detached), byteLength: 0 } }',
222+
);
214223
}
215224

216225
// Truncate output for ArrayBuffers using plural or singular bytes
@@ -294,15 +303,17 @@ assert.doesNotMatch(
294303
});
295304

296305
// Now check that declaring a TypedArray in a different context works the same.
297-
[ Float32Array,
306+
[
307+
Float32Array,
298308
Float64Array,
299309
Int16Array,
300310
Int32Array,
301311
Int8Array,
302312
Uint16Array,
303313
Uint32Array,
304314
Uint8Array,
305-
Uint8ClampedArray ].forEach((constructor) => {
315+
Uint8ClampedArray,
316+
].forEach((constructor) => {
306317
const length = 2;
307318
const byteLength = length * constructor.BYTES_PER_ELEMENT;
308319
const array = vm.runInNewContext(

0 commit comments

Comments
 (0)