Fix infinite loop in loading num_glyphs within sanitizer

This commit is contained in:
Behdad Esfahbod 2018-07-23 14:44:10 -07:00
parent e22a48ac95
commit 61eddbd8ef
2 changed files with 13 additions and 4 deletions

View File

@ -164,7 +164,8 @@ struct hb_sanitize_context_t :
start (nullptr), end (nullptr), start (nullptr), end (nullptr),
writable (false), edit_count (0), max_ops (0), writable (false), edit_count (0), max_ops (0),
blob (nullptr), blob (nullptr),
num_glyphs (0) {} num_glyphs (65536),
num_glyphs_set (false) {}
inline const char *get_name (void) { return "SANITIZE"; } inline const char *get_name (void) { return "SANITIZE"; }
template <typename T, typename F> template <typename T, typename F>
@ -182,7 +183,11 @@ struct hb_sanitize_context_t :
this->writable = false; this->writable = false;
} }
inline void set_num_glyphs (unsigned int num_glyphs_) { num_glyphs = num_glyphs_; } inline void set_num_glyphs (unsigned int num_glyphs_)
{
num_glyphs = num_glyphs_;
num_glyphs_set = true;
}
inline unsigned int get_num_glyphs (void) { return num_glyphs; } inline unsigned int get_num_glyphs (void) { return num_glyphs; }
inline void start_processing (void) inline void start_processing (void)
@ -348,7 +353,8 @@ struct hb_sanitize_context_t :
template <typename Type> template <typename Type>
inline hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag) inline hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
{ {
set_num_glyphs (face->get_num_glyphs ()); if (!num_glyphs_set)
set_num_glyphs (face->get_num_glyphs ());
return sanitize_blob<Type> (face->reference_table (tableTag)); return sanitize_blob<Type> (face->reference_table (tableTag));
} }
@ -360,6 +366,7 @@ struct hb_sanitize_context_t :
mutable int max_ops; mutable int max_ops;
hb_blob_t *blob; hb_blob_t *blob;
unsigned int num_glyphs; unsigned int num_glyphs;
bool num_glyphs_set;
}; };

View File

@ -38,7 +38,9 @@ hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_
void void
hb_face_t::load_num_glyphs (void) const hb_face_t::load_num_glyphs (void) const
{ {
hb_blob_t *maxp_blob = OT::hb_sanitize_context_t().reference_table<OT::maxp> (this); OT::hb_sanitize_context_t c = OT::hb_sanitize_context_t();
c.set_num_glyphs (0); /* So we don't recurse ad infinitum. */
hb_blob_t *maxp_blob = c.reference_table<OT::maxp> (this);
const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> (); const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> ();
num_glyphs = maxp_table->get_num_glyphs (); num_glyphs = maxp_table->get_num_glyphs ();
hb_blob_destroy (maxp_blob); hb_blob_destroy (maxp_blob);