[cbdt] Start fixing sanitization (or lack thereof)

This commit is contained in:
Behdad Esfahbod 2016-12-02 19:25:54 -08:00
parent b92ba7bafc
commit 4b58c9e326
2 changed files with 68 additions and 31 deletions

View File

@ -33,6 +33,12 @@ namespace OT {
struct SmallGlyphMetrics
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
BYTE height;
BYTE width;
CHAR bearingX;
@ -42,7 +48,14 @@ struct SmallGlyphMetrics
DEFINE_SIZE_STATIC(5);
};
struct SBitLineMetrics {
struct SBitLineMetrics
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
CHAR ascender;
CHAR decender;
BYTE widthMax;
@ -61,6 +74,14 @@ struct SBitLineMetrics {
struct BitmapSizeTable
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
horizontal.sanitize (c) &&
vertical.sanitize (c));
}
ULONG indexSubtableArrayOffset;
ULONG indexTablesSize;
ULONG numberOfIndexSubtables;
@ -94,41 +115,49 @@ struct IndexSubHeader
USHORT indexFormat;
USHORT imageFormat;
ULONG imageDataOffset;
DEFINE_SIZE_STATIC(8);
};
struct IndexSubtableFormat1
{
IndexSubHeader header;
ULONG offsetArray[VAR];
ULONG offsetArrayZ[VAR];
DEFINE_SIZE_ARRAY(8, offsetArrayZ);
};
/*
* Glyph Bitmap Data Formats.
*/
struct GlyphBitmapDataFormat17
{
SmallGlyphMetrics glyphMetrics;
ULONG dataLen;
BYTE data[VAR];
BYTE dataZ[VAR];
DEFINE_SIZE_ARRAY(9, dataZ);
};
struct IndexSubtableArray
{
public:
const IndexSubtable* find_table(hb_codepoint_t glyph, unsigned int numTables) const
const IndexSubtable* find_table (hb_codepoint_t glyph, unsigned int numTables) const
{
for (unsigned int i = 0; i < numTables; ++i) {
unsigned int firstGlyphIndex = indexSubtables[i].firstGlyphIndex;
unsigned int lastGlyphIndex = indexSubtables[i].lastGlyphIndex;
for (unsigned int i = 0; i < numTables; ++i)
{
unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
return &indexSubtables[i];
return &indexSubtablesZ[i];
}
}
return NULL;
}
protected:
IndexSubtable indexSubtables[VAR];
IndexSubtable indexSubtablesZ[VAR];
};
/*
@ -144,17 +173,19 @@ struct CBLC
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (true);
return_trace (c->check_struct (this) &&
likely (version.major == 2 || version.major == 3) &&
sizeTables.sanitize (c));
}
public:
const BitmapSizeTable* find_table(hb_codepoint_t glyph) const
const BitmapSizeTable* find_table (hb_codepoint_t glyph) const
{
// TODO: Make it possible to select strike.
const uint32_t tableSize = numSizes;
for (uint32_t i = 0; i < tableSize; ++i) {
unsigned int startGlyphIndex = sizeTables[i].startGlyphIndex;
unsigned int endGlyphIndex = sizeTables[i].endGlyphIndex;
unsigned int count = sizeTables.len;
for (uint32_t i = 0; i < count; ++i) {
unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex;
unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex;
if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) {
return &sizeTables[i];
}
@ -163,10 +194,11 @@ struct CBLC
}
protected:
ULONG version;
ULONG numSizes;
FixedVersion<>version;
ArrayOf<BitmapSizeTable, ULONG> sizeTables;
BitmapSizeTable sizeTables[VAR];
public:
DEFINE_SIZE_ARRAY(8, sizeTables);
};
/*
@ -181,11 +213,16 @@ struct CBDT
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (true);
return_trace (c->check_struct (this) &&
likely (version.major == 2 || version.major == 3));
}
protected:
BYTE data[VAR];
FixedVersion<>version;
BYTE dataZ[VAR];
public:
DEFINE_SIZE_ARRAY(4, dataZ);
};
} /* namespace OT */

View File

@ -210,10 +210,10 @@ struct hb_ot_face_glyf_accelerator_t
struct hb_ot_face_cbdt_accelerator_t
{
hb_blob_t *cblc_blob = NULL;
hb_blob_t *cbdt_blob = NULL;
const OT::CBLC *cblc = NULL;
const OT::CBDT *cbdt = NULL;
hb_blob_t *cblc_blob;
hb_blob_t *cbdt_blob;
const OT::CBLC *cblc;
const OT::CBDT *cbdt;
float upem = 0.0f;
@ -223,6 +223,8 @@ struct hb_ot_face_cbdt_accelerator_t
this->cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT));
if (hb_blob_get_length (this->cblc_blob) == 0) {
cblc = NULL;
cbdt = NULL;
return; /* Not a bitmap font. */
}
cblc = OT::Sanitizer<OT::CBLC>::lock_instance (this->cblc_blob);
@ -233,11 +235,9 @@ struct hb_ot_face_cbdt_accelerator_t
inline void fini (void)
{
if (this->cblc_blob) {
hb_blob_destroy (this->cblc_blob);
hb_blob_destroy (this->cbdt_blob);
}
}
inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
{
@ -266,7 +266,7 @@ struct hb_ot_face_cbdt_accelerator_t
case 1: {
const OT::IndexSubtableFormat1& format1 =
OT::StructAtOffset<OT::IndexSubtableFormat1> (this->cblc, offsetToSubtable);
imageDataOffset += format1.offsetArray[glyph - subtable->firstGlyphIndex];
imageDataOffset += format1.offsetArrayZ[glyph - subtable->firstGlyphIndex];
switch (header.imageFormat) {
case 17: {
const OT::GlyphBitmapDataFormat17& glyphFormat17 =
@ -288,7 +288,7 @@ struct hb_ot_face_cbdt_accelerator_t
return false;
}
// Convert to the font units.
/* Convert to the font units. */
extents->x_bearing *= upem / (float)(sizeTable->ppemX);
extents->y_bearing *= upem / (float)(sizeTable->ppemY);
extents->width *= upem / (float)(sizeTable->ppemX);
@ -558,7 +558,7 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
bool ret = ot_font->glyf->get_extents (glyph, extents);
if ( !ret )
if (!ret)
ret = ot_font->cbdt->get_extents (glyph, extents);
extents->x_bearing = font->em_scale_x (extents->x_bearing);
extents->y_bearing = font->em_scale_y (extents->y_bearing);