Ensure that we handle indirect objects in all types of Opt entries in ChoiceWidget annotation dictionaries

I haven't got an example where the current code breaks, but given all the previous cases we've seen where PDF generators use indirect objects in Arrays it makes sense to fix this pro-actively.
I've modified the relevant unit-tests slightly, and they would *not* pass without the code changes in this patch.

*Note:* `Dict_getArray` only dereferences Array elements on the "top-level", to avoid recursion issues. Furthermore if you have to loop through the Array at the call-site anyway, then using `Dict_get` in combination with `XRef_fetchIfRef` is a tiny bit more efficient.
This commit is contained in:
Jonas Jenwald 2016-12-17 13:34:18 +01:00
parent a719b71e59
commit bd91f34513
2 changed files with 21 additions and 8 deletions

View File

@ -779,14 +779,16 @@ var ChoiceWidgetAnnotation = (function ChoiceWidgetAnnotationClosure() {
// it to an array of arrays as well for convenience in the display layer. // it to an array of arrays as well for convenience in the display layer.
this.data.options = []; this.data.options = [];
var options = params.dict.getArray('Opt'); var options = params.dict.get('Opt');
if (isArray(options)) { if (isArray(options)) {
var xref = params.xref;
for (var i = 0, ii = options.length; i < ii; i++) { for (var i = 0, ii = options.length; i < ii; i++) {
var option = options[i]; var option = xref.fetchIfRef(options[i]);
var isOptionArray = isArray(option);
this.data.options[i] = { this.data.options[i] = {
exportValue: isArray(option) ? option[0] : option, exportValue: isOptionArray ? xref.fetchIfRef(option[0]) : option,
displayValue: isArray(option) ? option[1] : option, displayValue: isOptionArray ? xref.fetchIfRef(option[1]) : option,
}; };
} }
} }

View File

@ -900,7 +900,12 @@ describe('Annotation layer', function() {
}); });
it('should handle option arrays with array elements', function() { it('should handle option arrays with array elements', function() {
var options = [['foo_export', 'Foo'], ['bar_export', 'Bar']]; var optionBarRef = new Ref(20, 0);
var optionBarStr = 'Bar';
var optionOneRef = new Ref(10, 0);
var optionOneArr = ['bar_export', optionBarRef];
var options = [['foo_export', 'Foo'], optionOneRef];
var expected = [ var expected = [
{ {
exportValue: 'foo_export', exportValue: 'foo_export',
@ -916,7 +921,9 @@ describe('Annotation layer', function() {
var choiceWidgetRef = new Ref(123, 0); var choiceWidgetRef = new Ref(123, 0);
var xref = new XRefMock([ var xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, } { ref: choiceWidgetRef, data: choiceWidgetDict, },
{ ref: optionBarRef, data: optionBarStr, },
{ ref: optionOneRef, data: optionOneArr, },
]); ]);
var choiceWidgetAnnotation = annotationFactory.create(xref, var choiceWidgetAnnotation = annotationFactory.create(xref,
@ -928,7 +935,10 @@ describe('Annotation layer', function() {
}); });
it('should handle option arrays with string elements', function() { it('should handle option arrays with string elements', function() {
var options = ['Foo', 'Bar']; var optionBarRef = new Ref(10, 0);
var optionBarStr = 'Bar';
var options = ['Foo', optionBarRef];
var expected = [ var expected = [
{ {
exportValue: 'Foo', exportValue: 'Foo',
@ -944,7 +954,8 @@ describe('Annotation layer', function() {
var choiceWidgetRef = new Ref(981, 0); var choiceWidgetRef = new Ref(981, 0);
var xref = new XRefMock([ var xref = new XRefMock([
{ ref: choiceWidgetRef, data: choiceWidgetDict, } { ref: choiceWidgetRef, data: choiceWidgetDict, },
{ ref: optionBarRef, data: optionBarStr, }
]); ]);
var choiceWidgetAnnotation = annotationFactory.create(xref, var choiceWidgetAnnotation = annotationFactory.create(xref,