From 2052ba343c0b222cf638e32f15622a237e423317 Mon Sep 17 00:00:00 2001 From: ud2 Date: Tue, 6 Jun 2023 17:06:00 +0800 Subject: [PATCH] fix(ext/console): fix inspecting large ArrayBuffers (#19373) --- cli/tests/unit/console_test.ts | 25 ++++++++++++++++++++++ ext/console/01_console.js | 39 ++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/cli/tests/unit/console_test.ts b/cli/tests/unit/console_test.ts index b177b956bb..4cedf35846 100644 --- a/cli/tests/unit/console_test.ts +++ b/cli/tests/unit/console_test.ts @@ -2193,6 +2193,31 @@ Deno.test(function inspectEmptyUint8Array() { ); }); +Deno.test(function inspectLargeArrayBuffer() { + const arrayBuffer = new ArrayBuffer(2 ** 32 + 1); + assertEquals( + Deno.inspect(arrayBuffer), + `ArrayBuffer { + [Uint8Contents]: <00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 4294967197 more bytes>, + byteLength: 4294967297 +}`, + ); + structuredClone(arrayBuffer, { transfer: [arrayBuffer] }); + assertEquals( + Deno.inspect(arrayBuffer), + "ArrayBuffer { (detached), byteLength: 0 }", + ); + + const sharedArrayBuffer = new SharedArrayBuffer(2 ** 32 + 1); + assertEquals( + Deno.inspect(sharedArrayBuffer), + `SharedArrayBuffer { + [Uint8Contents]: <00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 4294967197 more bytes>, + byteLength: 4294967297 +}`, + ); +}); + Deno.test(function inspectStringAbbreviation() { const LONG_STRING = "This is a really long string which will be abbreviated with ellipsis."; diff --git a/ext/console/01_console.js b/ext/console/01_console.js index 6cf3c6dcac..fbc36ca9c7 100644 --- a/ext/console/01_console.js +++ b/ext/console/01_console.js @@ -248,6 +248,17 @@ defineColorAlias("doubleunderline", "doubleUnderline"); // https://tc39.es/ecma262/#sec-get-sharedarraybuffer.prototype.bytelength let _getSharedArrayBufferByteLength; +function getSharedArrayBufferByteLength(value) { + // TODO(kt3k): add SharedArrayBuffer to primordials + _getSharedArrayBufferByteLength ??= ObjectGetOwnPropertyDescriptor( + // deno-lint-ignore prefer-primordials + SharedArrayBuffer.prototype, + "byteLength", + ).get; + + return FunctionPrototypeCall(_getSharedArrayBufferByteLength, value); +} + function isObjectLike(value) { return value !== null && typeof value === "object"; } @@ -428,15 +439,8 @@ export function isSetIterator( export function isSharedArrayBuffer( value, ) { - // TODO(kt3k): add SharedArrayBuffer to primordials - _getSharedArrayBufferByteLength ??= ObjectGetOwnPropertyDescriptor( - // deno-lint-ignore prefer-primordials - SharedArrayBuffer.prototype, - "byteLength", - ).get; - try { - FunctionPrototypeCall(_getSharedArrayBufferByteLength, value); + getSharedArrayBufferByteLength(value); return true; } catch { return false; @@ -1608,7 +1612,7 @@ const hexSliceLookupTable = function () { }(); function hexSlice(buf, start, end) { - const len = buf.length; + const len = TypedArrayPrototypeGetLength(buf); if (!start || start < 0) { start = 0; } @@ -1624,21 +1628,24 @@ function hexSlice(buf, start, end) { const arrayBufferRegExp = new SafeRegExp("(.{2})", "g"); function formatArrayBuffer(ctx, value) { + let valLen; + try { + valLen = ArrayBufferPrototypeGetByteLength(value); + } catch { + valLen = getSharedArrayBufferByteLength(value); + } + const len = MathMin(MathMax(0, ctx.maxArrayLength), valLen); let buffer; try { - buffer = new Uint8Array(value); + buffer = new Uint8Array(value, 0, len); } catch { return [ctx.stylize("(detached)", "special")]; } let str = StringPrototypeTrim( - StringPrototypeReplace( - hexSlice(buffer, 0, MathMin(ctx.maxArrayLength, buffer.length)), - arrayBufferRegExp, - "$1 ", - ), + StringPrototypeReplace(hexSlice(buffer), arrayBufferRegExp, "$1 "), ); - const remaining = buffer.length - ctx.maxArrayLength; + const remaining = valLen - len; if (remaining > 0) { str += ` ... ${remaining} more byte${remaining > 1 ? "s" : ""}`; }