Skip to content

Commit

Permalink
[glyf] Move GlyphHeader size checking to a static method
Browse files Browse the repository at this point in the history
  • Loading branch information
ebraminio committed Aug 24, 2019
1 parent 139d14d commit 07e467a
Showing 1 changed file with 36 additions and 33 deletions.
69 changes: 36 additions & 33 deletions src/hb-ot-glyf-table.hh
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ struct glyf
static void
_zero_instruction_length (hb_bytes_t glyph)
{
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
auto &glyph_header = GlyphHeader::from_bytes (glyph);
if (!glyph_header.is_simple_glyph ()) return; // only for simple glyphs

unsigned int instruction_len_offset = glyph_header.simple_instruction_len_offset ();
Expand All @@ -241,7 +241,7 @@ struct glyf

static bool _remove_composite_instruction_flag (hb_bytes_t glyph)
{
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
auto &glyph_header = GlyphHeader::from_bytes (glyph);
if (!glyph_header.is_composite_glyph ()) return true; // only for composites

/* remove WE_HAVE_INSTRUCTIONS from flags in dest */
Expand Down Expand Up @@ -279,6 +279,13 @@ struct glyf

struct GlyphHeader
{
static const GlyphHeader &from_bytes (hb_bytes_t glyph_bytes)
{
return glyph_bytes.length < GlyphHeader::static_size
? Null (GlyphHeader)
: StructAtOffset<GlyphHeader> (&glyph_bytes, 0);
}

unsigned int simple_instruction_len_offset () const
{ return static_size + 2 * numberOfContours; }

Expand All @@ -296,15 +303,17 @@ struct glyf
extents->height = hb_min (yMin, yMax) - extents->y_bearing;
}

bool has_data () const { return numberOfContours; }

protected:
HBINT16 numberOfContours; /* If the number of contours is
* greater than or equal to zero,
* this is a simple glyph; if negative,
* this is a composite glyph. */
FWORD xMin; /* Minimum x for coordinate data. */
FWORD yMin; /* Minimum y for coordinate data. */
FWORD xMax; /* Maximum x for coordinate data. */
FWORD yMax; /* Maximum y for coordinate data. */
HBINT16 numberOfContours;/* If the number of contours is
* greater than or equal to zero,
* this is a simple glyph; if negative,
* this is a composite glyph. */
FWORD xMin; /* Minimum x for coordinate data. */
FWORD yMin; /* Minimum y for coordinate data. */
FWORD xMax; /* Maximum x for coordinate data. */
FWORD yMax; /* Maximum y for coordinate data. */
public:
DEFINE_SIZE_STATIC (10);
};
Expand Down Expand Up @@ -381,10 +390,9 @@ struct glyf
unsigned int length,
CompositeGlyphHeader::Iterator *iterator /* OUT */)
{
if (length < GlyphHeader::static_size)
return false; /* Empty glyph; zero extents. */
auto &glyph_header = GlyphHeader::from_bytes (hb_bytes_t (glyph_data, length));
if (!glyph_header.has_data ()) return false; /* Empty glyph; zero extents. */

const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0);
if (glyph_header.is_composite_glyph ())
{
const CompositeGlyphHeader *possible =
Expand Down Expand Up @@ -464,17 +472,17 @@ struct glyf
bool remove_padding (unsigned int start_offset,
unsigned int *end_offset) const
{
if (*end_offset - start_offset < GlyphHeader::static_size) return true;

const char *glyph = ((const char *) glyf_table) + start_offset;
const char * const glyph_end = glyph + (*end_offset - start_offset);
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph, 0);
unsigned int glyph_length = *end_offset - start_offset;
auto &glyph_header = GlyphHeader::from_bytes (hb_bytes_t (glyph, glyph_length));
if (!glyph_header.has_data ()) return true;

const char *glyph_end = glyph + glyph_length;
if (glyph_header.is_composite_glyph ())
/* Trimming for composites not implemented.
* If removing hints it falls out of that. */
return true;
else if (glyph_header.is_simple_glyph ())
else
{
/* simple glyph w/contours, possibly trimmable */
glyph += glyph_header.simple_instruction_len_offset ();
Expand Down Expand Up @@ -563,14 +571,14 @@ struct glyf
bool get_instruction_length (hb_bytes_t glyph,
unsigned int * length /* OUT */) const
{
auto &glyph_header = GlyphHeader::from_bytes (glyph);
/* Empty glyph; no instructions. */
if (glyph.length < GlyphHeader::static_size)
if (!glyph_header.has_data ())
{
*length = 0;
// only 0 byte glyphs are healthy when missing GlyphHeader
return glyph.length == 0;
}
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
if (glyph_header.is_composite_glyph ())
{
unsigned int start = glyph.length;
Expand Down Expand Up @@ -627,16 +635,12 @@ struct glyf
if (!get_offsets (glyph, &start_offset, &end_offset))
return false;

if (end_offset - start_offset < GlyphHeader::static_size)
return true; /* Empty glyph; zero extents. */

const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table,
start_offset);
glyph_header.get_extents (extents);
GlyphHeader::from_bytes (hb_bytes_t ((const char *) glyf_table + start_offset,
end_offset - start_offset)).get_extents (extents);
return true;
}

hb_bytes_t bytes_for_glyph (const char * glyf, hb_codepoint_t gid)
hb_bytes_t bytes_for_glyph (const char *glyf, hb_codepoint_t gid)
{
unsigned int start_offset, end_offset;
if (unlikely (!(get_offsets (gid, &start_offset, &end_offset) &&
Expand All @@ -645,14 +649,13 @@ struct glyf
DEBUG_MSG (SUBSET, nullptr, "Unable to get offset or remove padding for %d", gid);
return hb_bytes_t ();
}
hb_bytes_t glyph = hb_bytes_t (glyf + start_offset, end_offset - start_offset);
if (glyph.length == 0) return glyph;
if (unlikely (glyph.length < GlyphHeader::static_size))
hb_bytes_t glyph_bytes = hb_bytes_t (glyf + start_offset, end_offset - start_offset);
if (!GlyphHeader::from_bytes (glyph_bytes).has_data ())
{
DEBUG_MSG (SUBSET, nullptr, "Glyph size smaller than minimum header %d", gid);
DEBUG_MSG (SUBSET, nullptr, "Empty or invalid glyph size, %d", gid);
return hb_bytes_t ();
}
return glyph;
return glyph_bytes;
}

private:
Expand Down Expand Up @@ -714,7 +717,7 @@ struct glyf
return ;
}

const GlyphHeader& header = StructAtOffset<GlyphHeader> (&source_glyph, 0);
const GlyphHeader& header = GlyphHeader::from_bytes (source_glyph);
DEBUG_MSG (SUBSET, nullptr, "new_gid %d drop %d instruction bytes "
"from %d byte source glyph",
new_gid, instruction_len, source_glyph.length);
Expand Down

0 comments on commit 07e467a

Please sign in to comment.