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:
commit
c4db4dd4ac
@ -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;
|
||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -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
BIN
test/pdfs/bug1146106.pdf
Normal file
Binary file not shown.
@ -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",
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user