diff --git a/src/hb-aat-layout-common-private.hh b/src/hb-aat-layout-common-private.hh index 2825b1813..d7f35052d 100644 --- a/src/hb-aat-layout-common-private.hh +++ b/src/hb-aat-layout-common-private.hh @@ -161,7 +161,7 @@ struct LookupFormat0 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (arrayZ.sanitize (c, c->num_glyphs)); + return_trace (arrayZ.sanitize (c, c->get_num_glyphs ())); } protected: @@ -625,7 +625,7 @@ struct hb_aat_apply_context_t : sanitizer (), lookup_index (0), debug_depth (0) { sanitizer.init (table); - sanitizer.num_glyphs = face->get_num_glyphs (); + sanitizer.set_num_glyphs (face->get_num_glyphs ()); sanitizer.start_processing (); } diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index f681c573f..26afb909b 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -182,6 +182,9 @@ struct hb_sanitize_context_t : this->writable = false; } + inline void set_num_glyphs (unsigned int num_glyphs_) { num_glyphs = num_glyphs_; } + inline unsigned int get_num_glyphs (void) { return num_glyphs; } + inline void start_processing (void) { this->start = hb_blob_get_data (this->blob, nullptr); @@ -275,8 +278,78 @@ struct hb_sanitize_context_t : return false; } + template + inline hb_blob_t *sanitize (hb_blob_t *blob) + { + bool sane; + + /* TODO is_sane() stuff */ + + init (blob); + + retry: + DEBUG_MSG_FUNC (SANITIZE, start, "start"); + + start_processing (); + + if (unlikely (!start)) + { + end_processing (); + return blob; + } + + Type *t = CastP (const_cast (start)); + + sane = t->sanitize (this); + if (sane) + { + if (edit_count) + { + DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %d edits; going for second round", edit_count); + + /* sanitize again to ensure no toe-stepping */ + edit_count = 0; + sane = t->sanitize (this); + if (edit_count) { + DEBUG_MSG_FUNC (SANITIZE, start, "requested %d edits in second round; FAILLING", edit_count); + sane = false; + } + } + } + else + { + if (edit_count && !writable) { + start = hb_blob_get_data_writable (blob, nullptr); + end = start + blob->length; + + if (start) + { + writable = true; + /* ok, we made it writable by relocating. try again */ + DEBUG_MSG_FUNC (SANITIZE, start, "retry"); + goto retry; + } + } + } + + end_processing (); + + DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED"); + if (sane) + { + blob->lock (); + return blob; + } + else + { + hb_blob_destroy (blob); + return hb_blob_get_empty (); + } + } + mutable unsigned int debug_depth; const char *start, *end; + private: bool writable; unsigned int edit_count; mutable int max_ops; @@ -290,72 +363,8 @@ struct hb_sanitize_context_t : template struct Sanitizer { - inline Sanitizer (unsigned int num_glyphs = 0) { c->num_glyphs = num_glyphs; } - - inline hb_blob_t *sanitize (hb_blob_t *blob) - { - bool sane; - - /* TODO is_sane() stuff */ - - c->init (blob); - - retry: - DEBUG_MSG_FUNC (SANITIZE, c->start, "start"); - - c->start_processing (); - - if (unlikely (!c->start)) { - c->end_processing (); - return blob; - } - - Type *t = CastP (const_cast (c->start)); - - sane = t->sanitize (c); - if (sane) { - if (c->edit_count) { - DEBUG_MSG_FUNC (SANITIZE, c->start, "passed first round with %d edits; going for second round", c->edit_count); - - /* sanitize again to ensure no toe-stepping */ - c->edit_count = 0; - sane = t->sanitize (c); - if (c->edit_count) { - DEBUG_MSG_FUNC (SANITIZE, c->start, "requested %d edits in second round; FAILLING", c->edit_count); - sane = false; - } - } - } else { - unsigned int edit_count = c->edit_count; - if (edit_count && !c->writable) { - c->start = hb_blob_get_data_writable (blob, nullptr); - c->end = c->start + blob->length; - - if (c->start) { - c->writable = true; - /* ok, we made it writable by relocating. try again */ - DEBUG_MSG_FUNC (SANITIZE, c->start, "retry"); - goto retry; - } - } - } - - c->end_processing (); - - DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED"); - if (sane) - { - blob->lock (); - return blob; - } - else - { - hb_blob_destroy (blob); - return hb_blob_get_empty (); - } - } - - inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; } + inline Sanitizer (unsigned int num_glyphs = 0) { c->set_num_glyphs (num_glyphs); } + inline hb_blob_t *sanitize (hb_blob_t *blob) { return c->sanitize (blob); } private: hb_sanitize_context_t c[1]; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 09a9517c4..bf644a67f 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -68,7 +68,7 @@ struct SBIXStrike { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - imageOffsetsZ.sanitize_shallow (c, c->num_glyphs + 1)); + imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1)); } protected: @@ -96,14 +96,11 @@ struct sbix { inline void init (hb_face_t *face) { - num_glyphs = hb_face_get_glyph_count (face); - - OT::Sanitizer sanitizer; - sanitizer.set_num_glyphs (num_glyphs); - sbix_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_sbix)); + /* XXX Using public API instead of private method to avoid link problem in dump_emoji. + * Kill that! */ + sbix_blob = OT::Sanitizer(hb_face_get_glyph_count (face)/*face->get_num_glyphs ()*/).sanitize (face->reference_table (HB_OT_TAG_sbix)); sbix_len = hb_blob_get_length (sbix_blob); sbix_table = sbix_blob->as (); - } inline void fini (void) @@ -134,7 +131,6 @@ struct sbix unsigned int sbix_len; unsigned int num_glyphs; - }; protected: diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index 21a8382c3..2ae1157dc 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -540,9 +540,6 @@ struct Feature c->try_set (&featureParams, new_offset) && !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) return_trace (false); - - if (c->edit_count > 1) - c->edit_count--; /* This was a "legitimate" edit; don't contribute to error count. */ } return_trace (true);