Try harder to find the next valid JPEG marker when decoding Scan data (issue 8182, issue 8189)
Tentatively fixes 8182 and fixes 8189.
This commit is contained in:
parent
cd5acf501e
commit
62eee8c782
@ -323,7 +323,7 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
decodeFn = decodeBaseline;
|
decodeFn = decodeBaseline;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mcu = 0, marker;
|
var mcu = 0, fileMarker;
|
||||||
var mcuExpected;
|
var mcuExpected;
|
||||||
if (componentsLength === 1) {
|
if (componentsLength === 1) {
|
||||||
mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;
|
mcuExpected = components[0].blocksPerLine * components[0].blocksPerColumn;
|
||||||
@ -365,14 +365,16 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
|
|
||||||
// find marker
|
// find marker
|
||||||
bitsCount = 0;
|
bitsCount = 0;
|
||||||
marker = (data[offset] << 8) | data[offset + 1];
|
fileMarker = findNextFileMarker(data, offset);
|
||||||
// Some bad images seem to pad Scan blocks with zero bytes, skip past
|
// 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).
|
// those to attempt to find a valid marker (fixes issue4090.pdf).
|
||||||
while (data[offset] === 0x00 && offset < data.length - 1) {
|
if (fileMarker && fileMarker.invalid) {
|
||||||
offset++;
|
warn('decodeScan - unexpected MCU data, next marker is: ' +
|
||||||
marker = (data[offset] << 8) | data[offset + 1];
|
fileMarker.invalid);
|
||||||
|
offset = fileMarker.offset;
|
||||||
}
|
}
|
||||||
if (marker <= 0xFF00) {
|
var marker = fileMarker && fileMarker.marker;
|
||||||
|
if (!marker || marker <= 0xFF00) {
|
||||||
error('JPEG error: marker was not found');
|
error('JPEG error: marker was not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,6 +385,15 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileMarker = findNextFileMarker(data, offset);
|
||||||
|
// Some images include more Scan blocks than expected, skip past those and
|
||||||
|
// attempt to find the next valid marker (fixes issue8182.pdf).
|
||||||
|
if (fileMarker && fileMarker.invalid) {
|
||||||
|
warn('decodeScan - unexpected Scan data, next marker is: ' +
|
||||||
|
fileMarker.invalid);
|
||||||
|
offset = fileMarker.offset;
|
||||||
|
}
|
||||||
|
|
||||||
return offset - startOffset;
|
return offset - startOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,6 +605,39 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
return a <= 0 ? 0 : a >= 255 ? 255 : a;
|
return a <= 0 ? 0 : a >= 255 ? 255 : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findNextFileMarker(data, currentPos, startPos) {
|
||||||
|
function peekUint16(pos) {
|
||||||
|
return (data[pos] << 8) | data[pos + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxPos = data.length - 1;
|
||||||
|
var newPos = startPos < currentPos ? startPos : currentPos;
|
||||||
|
|
||||||
|
if (currentPos >= maxPos) {
|
||||||
|
return null; // Don't attempt to read non-existent data and just return.
|
||||||
|
}
|
||||||
|
var currentMarker = peekUint16(currentPos);
|
||||||
|
if (currentMarker >= 0xFFC0 && currentMarker <= 0xFFFE) {
|
||||||
|
return {
|
||||||
|
invalid: null,
|
||||||
|
marker: currentMarker,
|
||||||
|
offset: currentPos,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var newMarker = peekUint16(newPos);
|
||||||
|
while (!(newMarker >= 0xFFC0 && newMarker <= 0xFFFE)) {
|
||||||
|
if (++newPos >= maxPos) {
|
||||||
|
return null; // Don't attempt to read non-existent data and just return.
|
||||||
|
}
|
||||||
|
newMarker = peekUint16(newPos);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
invalid: currentMarker.toString(16),
|
||||||
|
marker: newMarker,
|
||||||
|
offset: newPos,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
JpegImage.prototype = {
|
JpegImage.prototype = {
|
||||||
parse: function parse(data) {
|
parse: function parse(data) {
|
||||||
|
|
||||||
@ -604,25 +648,14 @@ var JpegImage = (function JpegImageClosure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function readDataBlock() {
|
function readDataBlock() {
|
||||||
function isValidMarkerAt(pos) {
|
|
||||||
if (pos < data.length - 1) {
|
|
||||||
return (data[pos] === 0xFF &&
|
|
||||||
data[pos + 1] >= 0xC0 && data[pos + 1] <= 0xFE);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var length = readUint16();
|
var length = readUint16();
|
||||||
var endOffset = offset + length - 2;
|
var endOffset = offset + length - 2;
|
||||||
|
|
||||||
if (!isValidMarkerAt(endOffset)) {
|
var fileMarker = findNextFileMarker(data, endOffset, offset);
|
||||||
|
if (fileMarker && fileMarker.invalid) {
|
||||||
warn('readDataBlock - incorrect length, next marker is: ' +
|
warn('readDataBlock - incorrect length, next marker is: ' +
|
||||||
(data[endOffset] << 8 | data[endOffset + 1]).toString('16'));
|
fileMarker.invalid);
|
||||||
var pos = offset;
|
endOffset = fileMarker.offset;
|
||||||
while (!isValidMarkerAt(pos)) {
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
endOffset = pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var array = data.subarray(offset, endOffset);
|
var array = data.subarray(offset, endOffset);
|
||||||
|
1
test/pdfs/issue8182.pdf.link
Normal file
1
test/pdfs/issue8182.pdf.link
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://github.com/mozilla/pdf.js/files/861340/PDF.with.blank.pages.pdf
|
@ -740,6 +740,14 @@
|
|||||||
"link": true,
|
"link": true,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue8182",
|
||||||
|
"file": "pdfs/issue8182.pdf",
|
||||||
|
"md5": "e295ae13dcbefd449f9a4957aed5e582",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": true,
|
||||||
|
"lastPage": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "txt2pdf",
|
{ "id": "txt2pdf",
|
||||||
"file": "pdfs/txt2pdf.pdf",
|
"file": "pdfs/txt2pdf.pdf",
|
||||||
"md5": "02cefa0f5e8d96313bb05163b2f88c8c",
|
"md5": "02cefa0f5e8d96313bb05163b2f88c8c",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user