From 2ebfa11c8ac2d834231b53cd26377332ee82bba8 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Sun, 12 Jan 2025 12:23:31 +1100 Subject: [PATCH] fix(cbor): incorrect decoding with subarrays --- cbor/_common_decode.ts | 14 +++++++------- cbor/decode_cbor_test.ts | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/cbor/_common_decode.ts b/cbor/_common_decode.ts index 0ff46d118082..28a60ea95d41 100644 --- a/cbor/_common_decode.ts +++ b/cbor/_common_decode.ts @@ -13,13 +13,13 @@ function calcLength( const view = new DataView(input.buffer); switch (aI) { case 24: - return [view.getUint8(offset), offset + 1]; + return [view.getUint8(offset + input.byteOffset), offset + 1]; case 25: - return [view.getUint16(offset), offset + 2]; + return [view.getUint16(offset + input.byteOffset), offset + 2]; case 26: - return [view.getUint32(offset), offset + 4]; + return [view.getUint32(offset + input.byteOffset), offset + 4]; default: // Only possible for it to be 27 - return [view.getBigUint64(offset), offset + 8]; + return [view.getBigUint64(offset + input.byteOffset), offset + 8]; } } @@ -315,11 +315,11 @@ function decodeSeven( const view = new DataView(input.buffer); switch (aI) { case 25: - return [view.getFloat16(offset), offset + 2]; + return [view.getFloat16(offset + input.byteOffset), offset + 2]; case 26: - return [view.getFloat32(offset), offset + 4]; + return [view.getFloat32(offset + input.byteOffset), offset + 4]; case 27: - return [view.getFloat64(offset), offset + 8]; + return [view.getFloat64(offset + input.byteOffset), offset + 8]; default: throw new RangeError( `Cannot decode value (0b111_${aI.toString(2).padStart(5, "0")})`, diff --git a/cbor/decode_cbor_test.ts b/cbor/decode_cbor_test.ts index 656841d60811..b1d89f671902 100644 --- a/cbor/decode_cbor_test.ts +++ b/cbor/decode_cbor_test.ts @@ -814,3 +814,35 @@ Deno.test("decodeCbor() rejecting tagNumber 259 due to invalid indefinite length "More bytes were expected", ); }); + +Deno.test("decodeCbor() correctly decoding with subarrays", () => { + let encodedData = encodeCbor(0); + let buffer = new Uint8Array(encodedData.length + 7); + buffer.set(encodedData, 7); + assertEquals(decodeCbor(buffer.subarray(7)), 0); + + encodedData = encodeCbor(24); + buffer = new Uint8Array(encodedData.length + 7); + buffer.set(encodedData, 7); + assertEquals(decodeCbor(buffer.subarray(7)), 24); + + encodedData = encodeCbor(2 ** 8); + buffer = new Uint8Array(encodedData.length + 7); + buffer.set(encodedData, 7); + assertEquals(decodeCbor(buffer.subarray(7)), 2 ** 8); + + encodedData = encodeCbor(2 ** 16); + buffer = new Uint8Array(encodedData.length + 7); + buffer.set(encodedData, 7); + assertEquals(decodeCbor(buffer.subarray(7)), 2 ** 16); + + encodedData = encodeCbor(2 ** 32); + buffer = new Uint8Array(encodedData.length + 7); + buffer.set(encodedData, 7); + assertEquals(decodeCbor(buffer.subarray(7)), 2n ** 32n); + + encodedData = encodeCbor(3.14); + buffer = new Uint8Array(encodedData.length + 7); + buffer.set(encodedData, 7); + assertEquals(decodeCbor(buffer.subarray(7)), 3.14); +});