From 1362cd91d0f9816825e5f179eed174e92c4f2ccd Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Thu, 12 Jan 2023 14:43:56 +0100 Subject: [PATCH] Improve input validation in `PDFDataTransportStream._onReceiveData` (PR 15908 follow-up) The mozilla-central [method `PdfDataListener.readData`](https://searchfox.org/mozilla-central/rev/893a8f062ec6144c84403fbfb0a57234418b89cf/toolkit/components/pdfjs/content/PdfStreamConverter.jsm#207-210) can return `null`, hence it seems like a very good idea to update `PDFDataTransportStream._onReceiveData` to handle that gracefully since the current code will throw in that case. Also, improves the JSDocs for the `PDFDataRangeTransport` class in the API. --- src/display/api.js | 29 ++++++++++++++++++++++++++++- src/display/transport_stream.js | 7 ++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/display/api.js b/src/display/api.js index 86564b63e..c999d1550 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -665,7 +665,7 @@ class PDFDocumentLoadingTask { class PDFDataRangeTransport { /** * @param {number} length - * @param {Uint8Array} initialData + * @param {Uint8Array|null} initialData * @param {boolean} [progressiveDone] * @param {string} [contentDispositionFilename] */ @@ -687,28 +687,48 @@ class PDFDataRangeTransport { this._readyCapability = createPromiseCapability(); } + /** + * @param {function} listener + */ addRangeListener(listener) { this._rangeListeners.push(listener); } + /** + * @param {function} listener + */ addProgressListener(listener) { this._progressListeners.push(listener); } + /** + * @param {function} listener + */ addProgressiveReadListener(listener) { this._progressiveReadListeners.push(listener); } + /** + * @param {function} listener + */ addProgressiveDoneListener(listener) { this._progressiveDoneListeners.push(listener); } + /** + * @param {number} begin + * @param {Uint8Array|null} chunk + */ onDataRange(begin, chunk) { for (const listener of this._rangeListeners) { listener(begin, chunk); } } + /** + * @param {number} loaded + * @param {number|undefined} total + */ onDataProgress(loaded, total) { this._readyCapability.promise.then(() => { for (const listener of this._progressListeners) { @@ -717,6 +737,9 @@ class PDFDataRangeTransport { }); } + /** + * @param {Uint8Array|null} chunk + */ onDataProgressiveRead(chunk) { this._readyCapability.promise.then(() => { for (const listener of this._progressiveReadListeners) { @@ -737,6 +760,10 @@ class PDFDataRangeTransport { this._readyCapability.resolve(); } + /** + * @param {number} begin + * @param {number} end + */ requestDataRange(begin, end) { unreachable("Abstract method PDFDataRangeTransport.requestDataRange"); } diff --git a/src/display/transport_stream.js b/src/display/transport_stream.js index 874cb5805..38460d55d 100644 --- a/src/display/transport_stream.js +++ b/src/display/transport_stream.js @@ -77,9 +77,10 @@ class PDFDataTransportStream { } _onReceiveData({ begin, chunk }) { - const buffer = this.#transferPdfData - ? chunk.buffer - : new Uint8Array(chunk).buffer; + const buffer = + this.#transferPdfData && chunk?.length >= 0 + ? chunk.buffer + : new Uint8Array(chunk).buffer; if (begin === undefined) { if (this._fullRequestReader) {