Merge pull request #13796 from Snuffleupagus/issue-13794

Allow `StreamsSequenceStream.readBlock` to skip sub-streams with errors (issue 13794)
This commit is contained in:
Tim van der Meij 2021-07-27 22:25:58 +02:00 committed by GitHub
commit 336a74a0e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 6 deletions

View File

@ -127,7 +127,7 @@ class DecodeStream extends BaseStream {
} }
class StreamsSequenceStream extends DecodeStream { class StreamsSequenceStream extends DecodeStream {
constructor(streams) { constructor(streams, onError = null) {
let maybeLength = 0; let maybeLength = 0;
for (const stream of streams) { for (const stream of streams) {
maybeLength += maybeLength +=
@ -138,6 +138,7 @@ class StreamsSequenceStream extends DecodeStream {
super(maybeLength); super(maybeLength);
this.streams = streams; this.streams = streams;
this._onError = onError;
} }
readBlock() { readBlock() {
@ -147,7 +148,16 @@ class StreamsSequenceStream extends DecodeStream {
return; return;
} }
const stream = streams.shift(); const stream = streams.shift();
const chunk = stream.getBytes(); let chunk;
try {
chunk = stream.getBytes();
} catch (reason) {
if (this._onError) {
this._onError(reason, stream.dict && stream.dict.objId);
return;
}
throw reason;
}
const bufferLength = this.bufferLength; const bufferLength = this.bufferLength;
const newLength = bufferLength + chunk.length; const newLength = bufferLength + chunk.length;
const buffer = this.ensureBuffer(newLength); const buffer = this.ensureBuffer(newLength);

View File

@ -30,6 +30,7 @@ import {
stringToPDFString, stringToPDFString,
stringToUTF8String, stringToUTF8String,
unreachable, unreachable,
UNSUPPORTED_FEATURES,
Util, Util,
warn, warn,
} from "../shared/util.js"; } from "../shared/util.js";
@ -225,16 +226,35 @@ class Page {
return shadow(this, "rotate", rotate); return shadow(this, "rotate", rotate);
} }
/**
* @private
*/
_onSubStreamError(handler, reason, objId) {
if (this.evaluatorOptions.ignoreErrors) {
// Error(s) when reading one of the /Contents sub-streams -- sending
// unsupported feature notification and allow parsing to continue.
handler.send("UnsupportedFeature", {
featureId: UNSUPPORTED_FEATURES.errorContentSubStream,
});
warn(`getContentStream - ignoring sub-stream (${objId}): "${reason}".`);
return;
}
throw reason;
}
/** /**
* @returns {Promise<BaseStream>} * @returns {Promise<BaseStream>}
*/ */
getContentStream() { getContentStream(handler) {
return this.pdfManager.ensure(this, "content").then(content => { return this.pdfManager.ensure(this, "content").then(content => {
if (content instanceof BaseStream) { if (content instanceof BaseStream) {
return content; return content;
} }
if (Array.isArray(content)) { if (Array.isArray(content)) {
return new StreamsSequenceStream(content); return new StreamsSequenceStream(
content,
this._onSubStreamError.bind(this, handler)
);
} }
// Replace non-existent page content with empty content. // Replace non-existent page content with empty content.
return new NullStream(); return new NullStream();
@ -307,7 +327,7 @@ class Page {
renderInteractiveForms, renderInteractiveForms,
annotationStorage, annotationStorage,
}) { }) {
const contentStreamPromise = this.getContentStream(); const contentStreamPromise = this.getContentStream(handler);
const resourcesPromise = this.loadResources([ const resourcesPromise = this.loadResources([
"ColorSpace", "ColorSpace",
"ExtGState", "ExtGState",
@ -417,7 +437,7 @@ class Page {
sink, sink,
combineTextItems, combineTextItems,
}) { }) {
const contentStreamPromise = this.getContentStream(); const contentStreamPromise = this.getContentStream(handler);
const resourcesPromise = this.loadResources([ const resourcesPromise = this.loadResources([
"ExtGState", "ExtGState",
"Font", "Font",

View File

@ -335,6 +335,7 @@ const UNSUPPORTED_FEATURES = {
errorFontBuildPath: "errorFontBuildPath", errorFontBuildPath: "errorFontBuildPath",
errorFontGetPath: "errorFontGetPath", errorFontGetPath: "errorFontGetPath",
errorMarkedContent: "errorMarkedContent", errorMarkedContent: "errorMarkedContent",
errorContentSubStream: "errorContentSubStream",
}; };
const PasswordResponses = { const PasswordResponses = {

View File

@ -0,0 +1 @@
https://github.com/mozilla/pdf.js/files/6876708/Scan-to-Mail-PDF1_.1.pdf

View File

@ -1399,6 +1399,14 @@
"lastPage": 7, "lastPage": 7,
"type": "eq" "type": "eq"
}, },
{ "id": "issue13794",
"file": "pdfs/issue13794.pdf",
"md5": "6b4c099e04c9df145198740f2bf75c48",
"link": true,
"rounds": 1,
"firstPage": 3,
"type": "eq"
},
{ "id": "issue9262", { "id": "issue9262",
"file": "pdfs/issue9262_reduced.pdf", "file": "pdfs/issue9262_reduced.pdf",
"md5": "5347ce2d7b3866625c22e115fd90e0de", "md5": "5347ce2d7b3866625c22e115fd90e0de",