Merge pull request #2584 from mduan/issue2537

Add sanitization of truetype fonts to fix #2531 and #2537
This commit is contained in:
Yury Delendik 2013-01-30 19:51:13 -08:00
commit 3273d72e2d
4 changed files with 80 additions and 2 deletions

View File

@ -3185,13 +3185,23 @@ var Font = (function FontClosure() {
font.pos += header.length - 2; font.pos += header.length - 2;
var numOfMetrics = int16(font.getBytes(2)); var numOfMetrics = int16(font.getBytes(2));
if (numOfMetrics > numGlyphs) {
info('The numOfMetrics (' + numOfMetrics + ') should not be ' +
'greater than the numGlyphs (' + numGlyphs + ')');
// Reduce numOfMetrics if it is greater than numGlyphs
numOfMetrics = numGlyphs;
header.data[34] = (numOfMetrics & 0xff00) >> 8;
header.data[35] = numOfMetrics & 0x00ff;
}
var numOfSidebearings = numGlyphs - numOfMetrics; var numOfSidebearings = numGlyphs - numOfMetrics;
var numMissing = numOfSidebearings - var numMissing = numOfSidebearings -
((hmtx.length - numOfMetrics * 4) >> 1); ((metrics.length - numOfMetrics * 4) >> 1);
if (numMissing > 0) { if (numMissing > 0) {
font.pos = (font.start ? font.start : 0) + metrics.offset; font.pos = (font.start ? font.start : 0) + metrics.offset;
var entries = ''; var entries = '';
for (var i = 0, ii = hmtx.length; i < ii; i++) for (var i = 0, ii = metrics.length; i < ii; i++)
entries += String.fromCharCode(font.getByte()); entries += String.fromCharCode(font.getByte());
for (var i = 0; i < numMissing; i++) for (var i = 0; i < numMissing; i++)
entries += '\x00\x00'; entries += '\x00\x00';
@ -3254,6 +3264,50 @@ var Font = (function FontClosure() {
return glyf.length; return glyf.length;
} }
function sanitizeHead(head, numGlyphs, locaLength) {
var data = head.data;
// Validate version:
// Should always be 0x00010000
var version = int32([data[0], data[1], data[2], data[3]]);
if (version >> 16 !== 1) {
info('Attempting to fix invalid version in head table: ' + version);
data[0] = 0;
data[1] = 1;
data[2] = 0;
data[3] = 0;
}
var indexToLocFormat = int16([data[50], data[51]]);
if (indexToLocFormat < 0 || indexToLocFormat > 1) {
info('Attempting to fix invalid indexToLocFormat in head table: ' +
indexToLocFormat);
// The value of indexToLocFormat should be 0 if the loca table
// consists of short offsets, and should be 1 if the loca table
// consists of long offsets.
//
// The number of entries in the loca table should be numGlyphs + 1.
//
// Using this information, we can work backwards to deduce if the
// size of each offset in the loca table, and thus figure out the
// appropriate value for indexToLocFormat.
var numGlyphsPlusOne = numGlyphs + 1;
if (locaLength === numGlyphsPlusOne << 1) {
// 0x0000 indicates the loca table consists of short offsets
data[50] = 0;
data[51] = 0;
} else if (locaLength === numGlyphsPlusOne << 2) {
// 0x0001 indicates the loca table consists of long offsets
data[50] = 0;
data[51] = 1;
} else {
warn('Could not fix indexToLocFormat: ' + indexToLocFormat);
}
}
}
function sanitizeGlyphLocations(loca, glyf, numGlyphs, function sanitizeGlyphLocations(loca, glyf, numGlyphs,
isGlyphLocationsLong) { isGlyphLocationsLong) {
var itemSize, itemDecode, itemEncode; var itemSize, itemDecode, itemEncode;
@ -3678,6 +3732,10 @@ var Font = (function FontClosure() {
sanitizeTTPrograms(fpgm, prep); sanitizeTTPrograms(fpgm, prep);
if (head) {
sanitizeHead(head, numGlyphs, loca.length);
}
var isGlyphLocationsLong = int16([head.data[50], head.data[51]]); var isGlyphLocationsLong = int16([head.data[50], head.data[51]]);
if (head && loca && glyf) { if (head && loca && glyf) {
sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong); sanitizeGlyphLocations(loca, glyf, numGlyphs, isGlyphLocationsLong);

View File

@ -0,0 +1 @@
http://www.rcjohnso.com/Looper/Looper.pdf

View File

@ -0,0 +1 @@
http://my.herk.ro/test.pdf

View File

@ -30,6 +30,24 @@
"rounds": 1, "rounds": 1,
"type": "eq" "type": "eq"
}, },
{ "id": "issue2531",
"file": "pdfs/issue2531.pdf",
"md5": "c58e6642d8a6e2ddd5e07a543ef8f30d",
"link": true,
"rounds": 1,
"firstPage": 4,
"lastPage": 4,
"type": "eq"
},
{ "id": "issue2537",
"file": "pdfs/issue2537.pdf",
"md5": "f56805a70ed3aa52aae5c16dd335f827",
"link": true,
"rounds": 1,
"firstPage": 1,
"lastPage": 1,
"type": "eq"
},
{ "id": "html5-canvas-cheat-sheet-load", { "id": "html5-canvas-cheat-sheet-load",
"file": "pdfs/canvas.pdf", "file": "pdfs/canvas.pdf",
"md5": "59510028561daf62e00bf9f6f066b033", "md5": "59510028561daf62e00bf9f6f066b033",