From 06f6f8719f92b4131a72eba4f66e90c4ab898d79 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 12 Apr 2020 12:27:11 +0200 Subject: [PATCH] Always skip over any additional, unexpected, RSTx (restart) markers in corrupt JPEG images (issue 11794) --- src/core/jpg.js | 50 ++++++++++++++++++++--------------- test/pdfs/issue11794.pdf.link | 1 + test/test_manifest.json | 8 ++++++ 3 files changed, 38 insertions(+), 21 deletions(-) create mode 100644 test/pdfs/issue11794.pdf.link diff --git a/src/core/jpg.js b/src/core/jpg.js index 53a2c1498..8df06677f 100644 --- a/src/core/jpg.js +++ b/src/core/jpg.js @@ -393,35 +393,42 @@ var JpegImage = (function JpegImageClosure() { } var h, v; - while (mcu < mcuExpected) { + while (mcu <= mcuExpected) { // reset interval stuff var mcuToRead = resetInterval ? Math.min(mcuExpected - mcu, resetInterval) : mcuExpected; - for (i = 0; i < componentsLength; i++) { - components[i].pred = 0; - } - eobrun = 0; - if (componentsLength === 1) { - component = components[0]; - for (n = 0; n < mcuToRead; n++) { - decodeBlock(component, decodeFn, mcu); - mcu++; + // The `mcuToRead === 0` case should only occur when all of the expected + // MCU data has been already parsed, i.e. when `mcu === mcuExpected`, but + // some corrupt JPEG images contain more data than intended and we thus + // want to skip over any extra RSTx markers below (fixes issue11794.pdf). + if (mcuToRead > 0) { + for (i = 0; i < componentsLength; i++) { + components[i].pred = 0; } - } else { - for (n = 0; n < mcuToRead; n++) { - for (i = 0; i < componentsLength; i++) { - component = components[i]; - h = component.h; - v = component.v; - for (j = 0; j < v; j++) { - for (k = 0; k < h; k++) { - decodeMcu(component, decodeFn, mcu, j, k); + eobrun = 0; + + if (componentsLength === 1) { + component = components[0]; + for (n = 0; n < mcuToRead; n++) { + decodeBlock(component, decodeFn, mcu); + mcu++; + } + } else { + for (n = 0; n < mcuToRead; n++) { + for (i = 0; i < componentsLength; i++) { + component = components[i]; + h = component.h; + v = component.v; + for (j = 0; j < v; j++) { + for (k = 0; k < h; k++) { + decodeMcu(component, decodeFn, mcu, j, k); + } } } + mcu++; } - mcu++; } } @@ -434,8 +441,9 @@ var JpegImage = (function JpegImageClosure() { if (fileMarker.invalid) { // Some bad images seem to pad Scan blocks with e.g. zero bytes, skip // past those to attempt to find a valid marker (fixes issue4090.pdf). + const partialMsg = mcuToRead > 0 ? "unexpected" : "excessive"; warn( - `decodeScan - unexpected MCU data, current marker is: ${fileMarker.invalid}` + `decodeScan - ${partialMsg} MCU data, current marker is: ${fileMarker.invalid}` ); offset = fileMarker.offset; } diff --git a/test/pdfs/issue11794.pdf.link b/test/pdfs/issue11794.pdf.link new file mode 100644 index 000000000..e1d1ed7a4 --- /dev/null +++ b/test/pdfs/issue11794.pdf.link @@ -0,0 +1 @@ +https://github.com/mozilla/pdf.js/files/4459214/test.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index 18880029e..b242e1ae5 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -2468,6 +2468,14 @@ "link": true, "type": "eq" }, + { "id": "issue11794", + "file": "pdfs/issue11794.pdf", + "md5": "00d17b10a5fd7c06cddd7a0d2066ecdd", + "rounds": 1, + "link": true, + "lastPage": 1, + "type": "eq" + }, { "id": "bug852992", "file": "pdfs/bug852992_reduced.pdf",