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 start = pos;
|
||||||
var bytes = this.bytes;
|
var bytes = this.bytes;
|
||||||
var format = bytes[pos++];
|
var format = bytes[pos++];
|
||||||
var fdSelect = [];
|
var fdSelect = [], rawBytes;
|
||||||
var i;
|
var i, invalidFirstGID = false;
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -865,11 +865,18 @@ var CFFParser = (function CFFParserClosure() {
|
|||||||
var id = bytes[pos++];
|
var id = bytes[pos++];
|
||||||
fdSelect.push(id);
|
fdSelect.push(id);
|
||||||
}
|
}
|
||||||
|
rawBytes = bytes.subarray(start, pos);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
var rangesCount = (bytes[pos++] << 8) | bytes[pos++];
|
var rangesCount = (bytes[pos++] << 8) | bytes[pos++];
|
||||||
for (i = 0; i < rangesCount; ++i) {
|
for (i = 0; i < rangesCount; ++i) {
|
||||||
var first = (bytes[pos++] << 8) | bytes[pos++];
|
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 fdIndex = bytes[pos++];
|
||||||
var next = (bytes[pos] << 8) | bytes[pos + 1];
|
var next = (bytes[pos] << 8) | bytes[pos + 1];
|
||||||
for (var j = first; j < next; ++j) {
|
for (var j = first; j < next; ++j) {
|
||||||
@ -878,13 +885,19 @@ var CFFParser = (function CFFParserClosure() {
|
|||||||
}
|
}
|
||||||
// Advance past the sentinel(next).
|
// Advance past the sentinel(next).
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
rawBytes = bytes.subarray(start, pos);
|
||||||
|
|
||||||
|
if (invalidFirstGID) {
|
||||||
|
rawBytes[3] = rawBytes[4] = 0; // Adjust the first range, first GID.
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error('Unknown fdselect format ' + format);
|
error('parseFDSelect: Unknown format "' + format + '".');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var end = pos;
|
assert(fdSelect.length === length, 'parseFDSelect: Invalid font data.');
|
||||||
return new CFFFDSelect(fdSelect, bytes.subarray(start, end));
|
|
||||||
|
return new CFFFDSelect(fdSelect, rawBytes);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return CFFParser;
|
return CFFParser;
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -37,6 +37,7 @@
|
|||||||
!bug1050040.pdf
|
!bug1050040.pdf
|
||||||
!bug1200096.pdf
|
!bug1200096.pdf
|
||||||
!bug1068432.pdf
|
!bug1068432.pdf
|
||||||
|
!bug1146106.pdf
|
||||||
!issue5564_reduced.pdf
|
!issue5564_reduced.pdf
|
||||||
!canvas.pdf
|
!canvas.pdf
|
||||||
!bug1132849.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,
|
"link": false,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "bug1146106",
|
||||||
|
"file": "pdfs/bug1146106.pdf",
|
||||||
|
"md5": "a323d3766da49ee40f7d5dff0aeb0cc1",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "issue1512",
|
{ "id": "issue1512",
|
||||||
"file": "pdfs/issue1512r.pdf",
|
"file": "pdfs/issue1512r.pdf",
|
||||||
"md5": "af48ede2658d99cca423147085c6609b",
|
"md5": "af48ede2658d99cca423147085c6609b",
|
||||||
|
@ -262,10 +262,12 @@ describe('CFFParser', function() {
|
|||||||
var bytes = new Uint8Array([0x00, // format
|
var bytes = new Uint8Array([0x00, // format
|
||||||
0x00, // gid: 0 fd: 0
|
0x00, // gid: 0 fd: 0
|
||||||
0x01 // gid: 1 fd: 1
|
0x01 // gid: 1 fd: 1
|
||||||
]);
|
]);
|
||||||
parser.bytes = bytes;
|
parser.bytes = bytes.slice();
|
||||||
var fdSelect = parser.parseFDSelect(0, 2);
|
var fdSelect = parser.parseFDSelect(0, 2);
|
||||||
|
|
||||||
expect(fdSelect.fdSelect).toEqual([0, 1]);
|
expect(fdSelect.fdSelect).toEqual([0, 1]);
|
||||||
|
expect(fdSelect.raw).toEqual(bytes);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses fdselect format 3', function() {
|
it('parses fdselect format 3', function() {
|
||||||
@ -273,13 +275,32 @@ describe('CFFParser', function() {
|
|||||||
0x00, 0x02, // range count
|
0x00, 0x02, // range count
|
||||||
0x00, 0x00, // first gid
|
0x00, 0x00, // first gid
|
||||||
0x09, // font dict 1 id
|
0x09, // font dict 1 id
|
||||||
0x00, 0x02, // nex gid
|
0x00, 0x02, // next gid
|
||||||
0x0a, // font dict 2 gid
|
0x0a, // font dict 2 id
|
||||||
0x00, 0x04 // sentinel (last gid)
|
0x00, 0x04 // sentinel (last gid)
|
||||||
]);
|
]);
|
||||||
parser.bytes = bytes;
|
parser.bytes = bytes.slice();
|
||||||
var fdSelect = parser.parseFDSelect(0, 2);
|
var fdSelect = parser.parseFDSelect(0, 4);
|
||||||
|
|
||||||
expect(fdSelect.fdSelect).toEqual([9, 9, 0xa, 0xa]);
|
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
|
// TODO fdArray
|
||||||
|
Loading…
x
Reference in New Issue
Block a user