Merge pull request #7361 from Snuffleupagus/bug-1146106

Attempt to recover valid `format 3` FDSelect data from broken CFF fonts (bug 1146106)
This commit is contained in:
Brendan Dahl 2016-06-07 11:47:51 -07:00
commit c4db4dd4ac
5 changed files with 54 additions and 12 deletions

View File

@ -856,8 +856,8 @@ var CFFParser = (function CFFParserClosure() {
var start = pos;
var bytes = this.bytes;
var format = bytes[pos++];
var fdSelect = [];
var i;
var fdSelect = [], rawBytes;
var i, invalidFirstGID = false;
switch (format) {
case 0:
@ -865,11 +865,18 @@ var CFFParser = (function CFFParserClosure() {
var id = bytes[pos++];
fdSelect.push(id);
}
rawBytes = bytes.subarray(start, pos);
break;
case 3:
var rangesCount = (bytes[pos++] << 8) | bytes[pos++];
for (i = 0; i < rangesCount; ++i) {
var first = (bytes[pos++] << 8) | bytes[pos++];
if (i === 0 && first !== 0) {
warn('parseFDSelect: The first range must have a first GID of 0' +
' -- trying to recover.');
invalidFirstGID = true;
first = 0;
}
var fdIndex = bytes[pos++];
var next = (bytes[pos] << 8) | bytes[pos + 1];
for (var j = first; j < next; ++j) {
@ -878,13 +885,19 @@ var CFFParser = (function CFFParserClosure() {
}
// Advance past the sentinel(next).
pos += 2;
rawBytes = bytes.subarray(start, pos);
if (invalidFirstGID) {
rawBytes[3] = rawBytes[4] = 0; // Adjust the first range, first GID.
}
break;
default:
error('Unknown fdselect format ' + format);
error('parseFDSelect: Unknown format "' + format + '".');
break;
}
var end = pos;
return new CFFFDSelect(fdSelect, bytes.subarray(start, end));
assert(fdSelect.length === length, 'parseFDSelect: Invalid font data.');
return new CFFFDSelect(fdSelect, rawBytes);
}
};
return CFFParser;

View File

@ -37,6 +37,7 @@
!bug1050040.pdf
!bug1200096.pdf
!bug1068432.pdf
!bug1146106.pdf
!issue5564_reduced.pdf
!canvas.pdf
!bug1132849.pdf

BIN
test/pdfs/bug1146106.pdf Normal file

Binary file not shown.

View File

@ -210,6 +210,13 @@
"link": false,
"type": "eq"
},
{ "id": "bug1146106",
"file": "pdfs/bug1146106.pdf",
"md5": "a323d3766da49ee40f7d5dff0aeb0cc1",
"rounds": 1,
"link": false,
"type": "eq"
},
{ "id": "issue1512",
"file": "pdfs/issue1512r.pdf",
"md5": "af48ede2658d99cca423147085c6609b",

View File

@ -262,10 +262,12 @@ describe('CFFParser', function() {
var bytes = new Uint8Array([0x00, // format
0x00, // gid: 0 fd: 0
0x01 // gid: 1 fd: 1
]);
parser.bytes = bytes;
]);
parser.bytes = bytes.slice();
var fdSelect = parser.parseFDSelect(0, 2);
expect(fdSelect.fdSelect).toEqual([0, 1]);
expect(fdSelect.raw).toEqual(bytes);
});
it('parses fdselect format 3', function() {
@ -273,13 +275,32 @@ describe('CFFParser', function() {
0x00, 0x02, // range count
0x00, 0x00, // first gid
0x09, // font dict 1 id
0x00, 0x02, // nex gid
0x0a, // font dict 2 gid
0x00, 0x02, // next gid
0x0a, // font dict 2 id
0x00, 0x04 // sentinel (last gid)
]);
parser.bytes = bytes;
var fdSelect = parser.parseFDSelect(0, 2);
]);
parser.bytes = bytes.slice();
var fdSelect = parser.parseFDSelect(0, 4);
expect(fdSelect.fdSelect).toEqual([9, 9, 0xa, 0xa]);
expect(fdSelect.raw).toEqual(bytes);
});
it('parses invalid fdselect format 3 (bug 1146106)', function() {
var bytes = new Uint8Array([0x03, // format
0x00, 0x02, // range count
0x00, 0x01, // first gid (invalid)
0x09, // font dict 1 id
0x00, 0x02, // next gid
0x0a, // font dict 2 id
0x00, 0x04 // sentinel (last gid)
]);
parser.bytes = bytes.slice();
var fdSelect = parser.parseFDSelect(0, 4);
expect(fdSelect.fdSelect).toEqual([9, 9, 0xa, 0xa]);
bytes[3] = bytes[4] = 0x00; // The adjusted first range, first gid.
expect(fdSelect.raw).toEqual(bytes);
});
// TODO fdArray