Ensure that there's always a setFont (Tf) operator before text rendering operators (issue 11651)
The PDF document in question is *corrupt*, since it contains multiple instances of incorrect operators. We obviously don't want to slow down parsing of *all* documents (since most are valid), just to accommodate a particular bad PDF generator, hence the reason for the inline check before calling the `ensureStateFont` method.
This commit is contained in:
parent
52749d1f0d
commit
65e514e063
@ -795,6 +795,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
return glyphs;
|
return glyphs;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ensureStateFont(state) {
|
||||||
|
if (state.font) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const reason = new FormatError(
|
||||||
|
"Missing setFont (Tf) operator before text rendering operator."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.options.ignoreErrors) {
|
||||||
|
// Missing setFont operator before text rendering operator -- sending
|
||||||
|
// unsupported feature notification and allow rendering to continue.
|
||||||
|
this.handler.send("UnsupportedFeature", {
|
||||||
|
featureId: UNSUPPORTED_FEATURES.font,
|
||||||
|
});
|
||||||
|
warn(`ensureStateFont: "${reason}".`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw reason;
|
||||||
|
},
|
||||||
|
|
||||||
setGState: function PartialEvaluator_setGState(
|
setGState: function PartialEvaluator_setGState(
|
||||||
resources,
|
resources,
|
||||||
gState,
|
gState,
|
||||||
@ -1364,9 +1384,17 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
case OPS.showText:
|
case OPS.showText:
|
||||||
|
if (!stateManager.state.font) {
|
||||||
|
self.ensureStateFont(stateManager.state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
args[0] = self.handleText(args[0], stateManager.state);
|
args[0] = self.handleText(args[0], stateManager.state);
|
||||||
break;
|
break;
|
||||||
case OPS.showSpacedText:
|
case OPS.showSpacedText:
|
||||||
|
if (!stateManager.state.font) {
|
||||||
|
self.ensureStateFont(stateManager.state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
var arr = args[0];
|
var arr = args[0];
|
||||||
var combinedGlyphs = [];
|
var combinedGlyphs = [];
|
||||||
var arrLength = arr.length;
|
var arrLength = arr.length;
|
||||||
@ -1386,11 +1414,19 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
fn = OPS.showText;
|
fn = OPS.showText;
|
||||||
break;
|
break;
|
||||||
case OPS.nextLineShowText:
|
case OPS.nextLineShowText:
|
||||||
|
if (!stateManager.state.font) {
|
||||||
|
self.ensureStateFont(stateManager.state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
operatorList.addOp(OPS.nextLine);
|
operatorList.addOp(OPS.nextLine);
|
||||||
args[0] = self.handleText(args[0], stateManager.state);
|
args[0] = self.handleText(args[0], stateManager.state);
|
||||||
fn = OPS.showText;
|
fn = OPS.showText;
|
||||||
break;
|
break;
|
||||||
case OPS.nextLineSetSpacingShowText:
|
case OPS.nextLineSetSpacingShowText:
|
||||||
|
if (!stateManager.state.font) {
|
||||||
|
self.ensureStateFont(stateManager.state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
operatorList.addOp(OPS.nextLine);
|
operatorList.addOp(OPS.nextLine);
|
||||||
operatorList.addOp(OPS.setWordSpacing, [args.shift()]);
|
operatorList.addOp(OPS.setWordSpacing, [args.shift()]);
|
||||||
operatorList.addOp(OPS.setCharSpacing, [args.shift()]);
|
operatorList.addOp(OPS.setCharSpacing, [args.shift()]);
|
||||||
@ -2056,6 +2092,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
textState.textLineMatrix = IDENTITY_MATRIX.slice();
|
textState.textLineMatrix = IDENTITY_MATRIX.slice();
|
||||||
break;
|
break;
|
||||||
case OPS.showSpacedText:
|
case OPS.showSpacedText:
|
||||||
|
if (!stateManager.state.font) {
|
||||||
|
self.ensureStateFont(stateManager.state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
var items = args[0];
|
var items = args[0];
|
||||||
var offset;
|
var offset;
|
||||||
for (var j = 0, jj = items.length; j < jj; j++) {
|
for (var j = 0, jj = items.length; j < jj; j++) {
|
||||||
@ -2105,14 +2145,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPS.showText:
|
case OPS.showText:
|
||||||
|
if (!stateManager.state.font) {
|
||||||
|
self.ensureStateFont(stateManager.state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
buildTextContentItem(args[0]);
|
buildTextContentItem(args[0]);
|
||||||
break;
|
break;
|
||||||
case OPS.nextLineShowText:
|
case OPS.nextLineShowText:
|
||||||
|
if (!stateManager.state.font) {
|
||||||
|
self.ensureStateFont(stateManager.state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
flushTextContentItem();
|
flushTextContentItem();
|
||||||
textState.carriageReturn();
|
textState.carriageReturn();
|
||||||
buildTextContentItem(args[0]);
|
buildTextContentItem(args[0]);
|
||||||
break;
|
break;
|
||||||
case OPS.nextLineSetSpacingShowText:
|
case OPS.nextLineSetSpacingShowText:
|
||||||
|
if (!stateManager.state.font) {
|
||||||
|
self.ensureStateFont(stateManager.state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
flushTextContentItem();
|
flushTextContentItem();
|
||||||
textState.wordSpacing = args[0];
|
textState.wordSpacing = args[0];
|
||||||
textState.charSpacing = args[1];
|
textState.charSpacing = args[1];
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -89,6 +89,7 @@
|
|||||||
!issue11279.pdf
|
!issue11279.pdf
|
||||||
!issue11362.pdf
|
!issue11362.pdf
|
||||||
!issue11578_reduced.pdf
|
!issue11578_reduced.pdf
|
||||||
|
!issue11651.pdf
|
||||||
!bad-PageLabels.pdf
|
!bad-PageLabels.pdf
|
||||||
!decodeACSuccessive.pdf
|
!decodeACSuccessive.pdf
|
||||||
!filled-background.pdf
|
!filled-background.pdf
|
||||||
|
BIN
test/pdfs/issue11651.pdf
Normal file
BIN
test/pdfs/issue11651.pdf
Normal file
Binary file not shown.
@ -67,6 +67,20 @@
|
|||||||
"link": false,
|
"link": false,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue11651-eq",
|
||||||
|
"file": "pdfs/issue11651.pdf",
|
||||||
|
"md5": "375233ad8dc4181a06148f8412f35b91",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
|
{ "id": "issue11651-text",
|
||||||
|
"file": "pdfs/issue11651.pdf",
|
||||||
|
"md5": "375233ad8dc4181a06148f8412f35b91",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
{ "id": "issue1293",
|
{ "id": "issue1293",
|
||||||
"file": "pdfs/issue1293r.pdf",
|
"file": "pdfs/issue1293r.pdf",
|
||||||
"md5": "4a098f5051f34fab036f5bbe88f8deef",
|
"md5": "4a098f5051f34fab036f5bbe88f8deef",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user