From 4fb3d1322c88c03c0e4c5b3e9d3d24263cec6dc1 Mon Sep 17 00:00:00 2001 From: C-3PO Date: Thu, 5 Jul 2018 02:17:28 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Do=20not=20read=20beyond=20array?= =?UTF-8?q?buffer=20bounds?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ssn/getSolidpkg.ts | 7 ++----- src/ssn/streams/arrayBufferToStream.ts | 4 ++-- src/ssn/streams/streamSetMaxLength.ts | 2 +- src/ssn/verify/verifySolidpkg.ts | 1 + 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ssn/getSolidpkg.ts b/src/ssn/getSolidpkg.ts index a8a7167..b52851a 100644 --- a/src/ssn/getSolidpkg.ts +++ b/src/ssn/getSolidpkg.ts @@ -13,15 +13,12 @@ export default async function getSolidpkg(product: Product, from: number, to: nu if (!verifyProductName(product)) { throw new TypeError(`"${product}" is not a valid product.`); } - if (typeof from !== 'number' || (from | 0) !== from || from < -1) { + if (typeof from !== 'number' || (from | 0) !== from || from < -1 || from > 999) { throw new TypeError(`from must be an integer greater than or equal to -1 but it is "${from}"`); } - if (typeof to !== 'number' || (to | 0) !== to || to < 0) { + if (typeof to !== 'number' || (to | 0) !== to || to < 0 || to > 999) { throw new TypeError(`to must be an integer greater than or equal to 0 but it is "${to}"`); } - if (from >= to) { - throw new TypeError(`from must be less than to but "${from}" is not less than "${to}".`); - } //Download .solidpkg file const ssnFile = await getUrlContents({ host: 'cdn-patch.swtor.com', path: `/patch/${product}/${product}_${from}to${to}.solidpkg` }); diff --git a/src/ssn/streams/arrayBufferToStream.ts b/src/ssn/streams/arrayBufferToStream.ts index bd4066f..291ddb3 100644 --- a/src/ssn/streams/arrayBufferToStream.ts +++ b/src/ssn/streams/arrayBufferToStream.ts @@ -4,14 +4,14 @@ const BUFFER_SIZE = 16 * 1024; export default function arrayBufferToStream(arrayBuffer: ArrayBuffer, offset = 0): stream.Readable { if (offset < 0 || offset + 1 >= arrayBuffer.byteLength) { - throw new Error('Could not convert ArrayBuffer to ReadableStream; out of bounds.'); + throw new RangeError('Could not convert ArrayBuffer to ReadableStream; out of bounds.'); } let position = offset; const outStream = new stream.Readable({ encoding: 'binary', read(size) { - const chunkSize = size || BUFFER_SIZE; //TODO: we can probably remove BUFFER_SIZE + const chunkSize = Math.min(size || BUFFER_SIZE, arrayBuffer.byteLength - position); //TODO: we can probably remove BUFFER_SIZE let needMoreData: boolean; do { //If end is reached diff --git a/src/ssn/streams/streamSetMaxLength.ts b/src/ssn/streams/streamSetMaxLength.ts index 0270349..499caef 100644 --- a/src/ssn/streams/streamSetMaxLength.ts +++ b/src/ssn/streams/streamSetMaxLength.ts @@ -3,7 +3,7 @@ import * as stream from 'stream'; /** Takes the given ReadableStream and returns a ReadableStream with the same contents but that terminates after the given length. */ export default function streamSetMaxLength(inputStream: stream.Readable, maxLength: number): stream.Readable { if (maxLength <= 0) { - throw new Error('maxLength is out of bounds.'); + throw new RangeError('maxLength is out of bounds.'); } let remaining = maxLength; diff --git a/src/ssn/verify/verifySolidpkg.ts b/src/ssn/verify/verifySolidpkg.ts index 04c618a..ebdd383 100644 --- a/src/ssn/verify/verifySolidpkg.ts +++ b/src/ssn/verify/verifySolidpkg.ts @@ -53,6 +53,7 @@ export default function verifySolidpkg(file: ISolid, { product, from, to }: {pro } } + //64kb, 256kb, 512kb, 4mb if (!([0x1_0000, 0x4_0000, 0x8_0000, 0x40_0000]).includes(file.info['piece length'])) { throw new Error(`Expected piece length to be "65536", "262144", 524288" or "4194304" but it was "${file.info['piece length']}".`); }