Merge pull request #13796 from Snuffleupagus/issue-13794
Allow `StreamsSequenceStream.readBlock` to skip sub-streams with errors (issue 13794)
This commit is contained in:
commit
336a74a0e5
@ -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);
|
||||||
|
@ -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",
|
||||||
|
@ -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 = {
|
||||||
|
1
test/pdfs/issue13794.pdf.link
Normal file
1
test/pdfs/issue13794.pdf.link
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://github.com/mozilla/pdf.js/files/6876708/Scan-to-Mail-PDF1_.1.pdf
|
@ -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",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user