From 2d643efce5fc18a0dced219932337e9acb2de753 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 7 Feb 2026 12:17:28 +0100 Subject: [PATCH] Ensure that pending requests are resolved when calling `PDFDataTransportStreamReader.prototype.progressiveDone` Doing skip-cache reloading of https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf#disableRange=true in the latest Firefox Nightly version I noticed an *intermittent* bug, where the loadingBar would fill up but without the PDF ever rendering. Initially I was quite worried that the changes in PR 20602 had somehow caused this, however after a bunch of testing in a slightly older Nightly I was able to reproduce the problem there as well.[1] Instead I believe that this problem goes all the back to PR 10675, so still my fault, since the `progressiveDone` handling there was incomplete. Note how we only set the `this._done` property, but don't actually resolve any still pending requests. For reference, compare with the handling in the `PDFDataTransportStreamRangeReader.prototype._enqueue` method. Depending on the exact order in which the `PDFDataTransportStreamReader.prototype.{_enqueue, read, progressiveDone}` methods are invoked, which depends on how/when the PDF data arrives, the bug might occur. The reason that this bug hasn't been caught before now is likely that `disableRange=true` isn't used by default and Firefox users are unlikely to manually set that in e.g. `about:config`. --- [1] Possibly some timings changed to make it slightly more common, but given the intermittent nature of this it's difficult to tell. --- src/display/transport_stream.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/display/transport_stream.js b/src/display/transport_stream.js index 325eac676..32fdcee2d 100644 --- a/src/display/transport_stream.js +++ b/src/display/transport_stream.js @@ -187,6 +187,14 @@ class PDFDataTransportStreamReader extends BasePDFStreamReader { progressiveDone() { this._done ||= true; + + if (this._queuedChunks.length > 0) { + return; + } + for (const capability of this._requests) { + capability.resolve({ value: undefined, done: true }); + } + this._requests.length = 0; } }