[HarfBuzz] 'head' table issue

Behdad Esfahbod behdad at behdad.org
Wed Sep 15 12:11:52 PDT 2010

On 08/16/10 10:30, Jonathan Kew wrote:
> Hi Behdad,
> I think there's an issue with how the 'head' table is handled in harfbuzz-ng at the moment.
> hb_face_create_for_tables() loads the 'head' table and calls Sanitizer<head>::sanitize() on it. However, if sanitize() fails, the table gets replaced by the empty blob, which means that face->head_table does not point to a valid 'head' structure, and in particular, when GPOS code tries to use the unitsPerEm value to scale coordinates, it is accessing "random" memory.

Well, it's not "random", it's zero memory.  You see, in hb-ot-layout-private.h
it says:

  /* XXX div-by-zero / speed up */
  inline hb_position_t scale_x (int16_t v) { return (int64_t)
this->font->x_scale * v / this->face->head_table->unitsPerEm; }
  inline hb_position_t scale_y (int16_t v) { return (int64_t)
this->font->y_scale * v / this->face->head_table->unitsPerEm; }

Straight from "lets just get it work for now" during the hackfest!

My plan was to add an accessor for upem that would return 1024 if the value
found in head table is < 16 or > 16384.

> So it seems to me that hb_face_create_for_tables() needs to check that the 'head' table was successfully loaded, *and* has a usable (non-zero, at least) unitsPerEm value. But as that's the only field we care about, we could let hb_face_create_for_tables() store the unitsPerEm value directly into the face (checking that it is within the valid range), and then release the table; there's no need to hold on to the blob after initial creation of the face.

Generally I like to access stuff from the table directly.  But upem may be
important enough to save it in the face and even add public API for.  I need
it in my current work because I want to render the font at exactly "upem per
em" size.

I'll fix this one way or another in my current batch of hb patches and push out.


> Suggested patch attached.
> JK

More information about the HarfBuzz mailing list