bug 580100 - sanity-checking of hhea/hmtx tables. r=jdaggett

This commit is contained in:
Jonathan Kew 2010-07-22 10:25:23 +01:00
parent 2f92ddc5b8
commit 2fb90b25c6
4 changed files with 32 additions and 10 deletions

View File

@ -0,0 +1,7 @@
<html><head>
<style>@font-face{font-family:t;src:url(580100-bad_hhea_table.ttf);}
p.t{font-size:40px;font-family:t;}</style>
</head>
<body>
<p class="t">Lorem ipsum</p></body>
</html>

Binary file not shown.

View File

@ -76,3 +76,4 @@ load 532726-1.html
load 538065-1.html
load 546870-1.html
load balinese-letter-spacing.html
load 580100-1.html

View File

@ -215,14 +215,15 @@ gfxHarfBuzzShaper::GetGlyphMetrics(gfxContext *aContext,
glyph = mNumLongMetrics - 1;
}
if ((glyph + 1) * sizeof(HLongMetric) <= hb_blob_get_length(mHmtxTable)) {
const HMetrics* hmtx =
reinterpret_cast<const HMetrics*>(hb_blob_lock(mHmtxTable));
metrics->x_advance =
FloatToFixed(mFont->FUnitsToDevUnitsFactor() *
PRUint16(hmtx->metrics[glyph].advanceWidth));
hb_blob_unlock(mHmtxTable);
}
// glyph must be valid now, because we checked during initialization
// that mNumLongMetrics is > 0, and that the hmtx table is large enough
// to contain mNumLongMetrics records
const HMetrics* hmtx =
reinterpret_cast<const HMetrics*>(hb_blob_lock(mHmtxTable));
metrics->x_advance =
FloatToFixed(mFont->FUnitsToDevUnitsFactor() *
PRUint16(hmtx->metrics[glyph].advanceWidth));
hb_blob_unlock(mHmtxTable);
// TODO: set additional metrics if/when harfbuzz needs them
}
@ -365,8 +366,21 @@ gfxHarfBuzzShaper::InitTextRun(gfxContext *aContext,
mNumLongMetrics = hhea->numberOfHMetrics;
hb_blob_unlock(hheaTable);
mHmtxTable =
mFont->GetFontTable(TRUETYPE_TAG('h','m','t','x'));
if (mNumLongMetrics > 0 &&
PRInt16(hhea->metricDataFormat) == 0) {
// no point reading hmtx if number of entries is zero!
// in that case, we won't be able to use this font
// (this method will return FALSE below if mHmtx is null)
mHmtxTable =
mFont->GetFontTable(TRUETYPE_TAG('h','m','t','x'));
if (hb_blob_get_length(mHmtxTable) <
mNumLongMetrics * sizeof(HLongMetric)) {
// hmtx table is not large enough for the claimed
// number of entries: invalid, do not use.
hb_blob_destroy(mHmtxTable);
mHmtxTable = nsnull;
}
}
}
hb_blob_destroy(hheaTable);
}