From 76816c04fdba8bdf35e0681ddac9b8533dfed6b1 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Mon, 20 Jan 2025 10:46:44 -0800 Subject: [PATCH] util: inspect: avoid a crash on a DataView with a detached buffer --- lib/internal/util/inspect.js | 20 ++++++++++++++++++-- test/parallel/test-util-inspect.js | 19 +++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 60bee498e5ea8b..bc6b648190dd47 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -1099,6 +1099,23 @@ function formatRaw(ctx, value, recurseTimes, typedArray) { try { output = formatter(ctx, value, recurseTimes); for (i = 0; i < keys.length; i++) { + if ( + isDataView(value) + && ( + keys[i] === 'byteLength' + || keys[i] === 'byteOffset' + ) + ) { + try { + const buffer = new Uint8Array(value.buffer); + } catch { + ArrayPrototypePush( + output, + formatValue(ctx, value.buffer.byteLength) + ); + continue; + } + } ArrayPrototypePush( output, formatProperty(ctx, value, recurseTimes, keys[i], extrasType), @@ -1994,8 +2011,7 @@ function formatProperty(ctx, value, recurseTimes, key, type, desc, original = value) { let name, str; let extra = ' '; - desc ||= ObjectGetOwnPropertyDescriptor(value, key) || - { value: value[key], enumerable: true }; + desc ||= ObjectGetOwnPropertyDescriptor(value, key) || { value: value[key], enumerable: true }; if (desc.value !== undefined) { const diff = (ctx.compact !== true || type !== kObjectType) ? 2 : 3; ctx.indentationLvl += diff; diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 0b04e3b8dc7179..5be239b0891c82 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -206,11 +206,20 @@ assert.doesNotMatch( { const ab = new ArrayBuffer(42); + const dv = new DataView(ab); + assert.strictEqual(ab.byteLength, 42); new MessageChannel().port1.postMessage(ab, [ ab ]); assert.strictEqual(ab.byteLength, 0); - assert.strictEqual(util.inspect(ab), - 'ArrayBuffer { (detached), byteLength: 0 }'); + assert.strictEqual( + util.inspect(ab), + 'ArrayBuffer { (detached), byteLength: 0 }', + ); + + assert.strictEqual( + util.inspect(dv), + 'DataView { 0, 0, buffer: ArrayBuffer { (detached), byteLength: 0 } }', + ); } // Truncate output for ArrayBuffers using plural or singular bytes @@ -294,7 +303,8 @@ assert.doesNotMatch( }); // Now check that declaring a TypedArray in a different context works the same. -[ Float32Array, +[ + Float32Array, Float64Array, Int16Array, Int32Array, @@ -302,7 +312,8 @@ assert.doesNotMatch( Uint16Array, Uint32Array, Uint8Array, - Uint8ClampedArray ].forEach((constructor) => { + Uint8ClampedArray, +].forEach((constructor) => { const length = 2; const byteLength = length * constructor.BYTES_PER_ELEMENT; const array = vm.runInNewContext(