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

View File

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