diff --git a/src/core/parser.js b/src/core/parser.js index 470d9905b95178..da3dcd06264344 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -18,8 +18,8 @@ import { PredictorStream, RunLengthStream } from './stream'; import { - assert, FormatError, info, isNum, isSpace, isString, MissingDataException, - StreamType, warn + assert, bytesToString, FormatError, info, isNum, isSpace, isString, + MissingDataException, StreamType, warn } from '../shared/util'; import { Cmd, Dict, EOF, isCmd, isDict, isEOF, isName, Name, Ref @@ -532,7 +532,34 @@ var Parser = (function ParserClosure() { let actualLength = this._findStreamLength(startPos, ENDSTREAM_SIGNATURE); if (actualLength < 0) { - throw new FormatError('Missing endstream command.'); + // Only allow limited truncation of the endstream signature, + // to prevent false positives. + const MAX_TRUNCATION = 1; + // Check if the PDF generator included truncated endstream commands, + // such as e.g. "endstrea" (fixes issue10004.pdf). + for (let i = 1; i <= MAX_TRUNCATION; i++) { + const end = ENDSTREAM_SIGNATURE.length - i; + const TRUNCATED_SIGNATURE = ENDSTREAM_SIGNATURE.slice(0, end); + + let maybeLength = this._findStreamLength(startPos, + TRUNCATED_SIGNATURE); + if (maybeLength >= 0) { + // Ensure that the byte immediately following the truncated + // endstream command is a space, to prevent false positives. + const lastByte = stream.peekBytes(end + 1)[end]; + if (!isSpace(lastByte)) { + break; + } + info(`Found "${bytesToString(TRUNCATED_SIGNATURE)}" when ` + + 'searching for endstream command.'); + actualLength = maybeLength; + break; + } + } + + if (actualLength < 0) { + throw new FormatError('Missing endstream command.'); + } } length = actualLength; diff --git a/test/pdfs/issue10004.pdf.link b/test/pdfs/issue10004.pdf.link new file mode 100644 index 00000000000000..4e3abde0dadccf --- /dev/null +++ b/test/pdfs/issue10004.pdf.link @@ -0,0 +1 @@ +https://github.com/mozilla/pdf.js/files/2315390/2371410.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index e97557e79f3c86..2a0551496dbf83 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -726,6 +726,13 @@ "link": false, "type": "load" }, + { "id": "issue10004", + "file": "pdfs/issue10004.pdf", + "md5": "64d1853060cefe3be50e5c4617dd0505", + "rounds": 1, + "link": true, + "type": "load" + }, { "id": "issue7507", "file": "pdfs/issue7507.pdf", "md5": "f7aeaafe0c89b94436e94eaa63307303",