From de2118ed7a998a1df9b28fd1be96b4af89ed82c3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 17 Feb 2015 17:27:44 +0300 Subject: [PATCH] Make sanitize() a const method This makes a lot of code safer. We only try modifying the object in one place, after making sure it's safe to do so. So, do a const_cast<> in that one place... --- src/hb-open-file-private.hh | 15 ++-- src/hb-open-type-private.hh | 51 ++++++++----- src/hb-ot-cmap-table.hh | 35 ++++++--- src/hb-ot-head-table.hh | 6 +- src/hb-ot-hhea-table.hh | 3 +- src/hb-ot-hmtx-table.hh | 3 +- src/hb-ot-layout-common-private.hh | 58 +++++++++----- src/hb-ot-layout-gdef-table.hh | 30 +++++--- src/hb-ot-layout-gpos-table.hh | 108 ++++++++++++++++++--------- src/hb-ot-layout-gsub-table.hh | 58 ++++++++------ src/hb-ot-layout-gsubgpos-private.hh | 65 ++++++++++------ src/hb-ot-layout-jstf-table.hh | 12 ++- src/hb-ot-maxp-table.hh | 6 +- src/hb-ot-name-table.hh | 6 +- 14 files changed, 296 insertions(+), 160 deletions(-) diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh index 7500c32f1..178bc7ccb 100644 --- a/src/hb-open-file-private.hh +++ b/src/hb-open-file-private.hh @@ -53,7 +53,8 @@ struct TTCHeader; typedef struct TableRecord { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -102,7 +103,8 @@ typedef struct OffsetTable } public: - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); } @@ -130,7 +132,8 @@ struct TTCHeaderVersion1 inline unsigned int get_face_count (void) const { return table.len; } inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (table.sanitize (c, this)); } @@ -169,7 +172,8 @@ struct TTCHeader } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false); switch (u.header.version.major) { @@ -233,7 +237,8 @@ struct OpenTypeFontFile } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false); switch (u.tag) { diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 477d9e28b..4ed46c167 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -270,9 +270,9 @@ struct hb_sanitize_context_t } template - inline bool try_set (Type *obj, const ValueType &v) { + inline bool try_set (const Type *obj, const ValueType &v) { if (this->may_edit (obj, obj->static_size)) { - obj->set (v); + const_cast (obj)->set (v); return true; } return false; @@ -619,7 +619,8 @@ struct IntType static inline int cmp (const IntType *a, const IntType *b) { return b->cmp (*a); } inline int cmp (IntType va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; } inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +1; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (likely (c->check_struct (this))); } @@ -646,7 +647,8 @@ typedef USHORT UFWORD; * 1904. The value is represented as a signed 64-bit integer. */ struct LONGDATETIME { - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (likely (c->check_struct (this))); } @@ -719,7 +721,8 @@ struct FixedVersion { inline uint32_t to_int (void) const { return (major << 16) + minor; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -747,33 +750,35 @@ struct OffsetTo : Offset return StructAtOffset (base, offset); } - inline Type& serialize (hb_serialize_context_t *c, void *base) + inline Type& serialize (hb_serialize_context_t *c, const void *base) { Type *t = c->start_embed (); this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ return *t; } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); unsigned int offset = *this; if (unlikely (!offset)) return TRACE_RETURN (true); - Type &obj = StructAtOffset (base, offset); + const Type &obj = StructAtOffset (base, offset); return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); } template - inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); unsigned int offset = *this; if (unlikely (!offset)) return TRACE_RETURN (true); - Type &obj = StructAtOffset (base, offset); + const Type &obj = StructAtOffset (base, offset); return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); } /* Set the offset to Null */ - inline bool neuter (hb_sanitize_context_t *c) { + inline bool neuter (hb_sanitize_context_t *c) const { return c->try_set (this, 0); } DEFINE_SIZE_STATIC (sizeof(OffsetType)); @@ -838,7 +843,8 @@ struct ArrayOf return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); @@ -853,7 +859,8 @@ struct ArrayOf return TRACE_RETURN (true); } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); unsigned int count = len; @@ -863,7 +870,8 @@ struct ArrayOf return TRACE_RETURN (true); } template - inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); unsigned int count = len; @@ -884,7 +892,8 @@ struct ArrayOf } private: - inline bool sanitize_shallow (hb_sanitize_context_t *c) { + inline bool sanitize_shallow (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len)); } @@ -910,12 +919,14 @@ struct OffsetListOf : OffsetArrayOf return this+this->array[i]; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (OffsetArrayOf::sanitize (c, this)); } template - inline bool sanitize (hb_sanitize_context_t *c, T user_data) { + inline bool sanitize (hb_sanitize_context_t *c, T user_data) const + { TRACE_SANITIZE (this); return TRACE_RETURN (OffsetArrayOf::sanitize (c, this, user_data)); } @@ -949,12 +960,14 @@ struct HeadlessArrayOf return TRACE_RETURN (true); } - inline bool sanitize_shallow (hb_sanitize_context_t *c) { + inline bool sanitize_shallow (hb_sanitize_context_t *c) const + { return c->check_struct (this) && c->check_array (this, Type::static_size, len); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index d53141157..048231255 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -51,7 +51,8 @@ struct CmapSubtableFormat0 return true; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -125,7 +126,7 @@ struct CmapSubtableFormat4 return true; } - inline bool sanitize (hb_sanitize_context_t *c) + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) @@ -183,7 +184,8 @@ struct CmapSubtableLongGroup return 0; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -210,7 +212,8 @@ struct CmapSubtableTrimmed return true; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c)); } @@ -242,7 +245,8 @@ struct CmapSubtableLongSegmented return true; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c)); } @@ -288,7 +292,8 @@ struct UnicodeValueRange return 0; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -309,7 +314,8 @@ struct UVSMapping return unicodeValue.cmp (codepoint); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -348,7 +354,8 @@ struct VariationSelectorRecord return varSelector.cmp (variation_selector); } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && defaultUVS.sanitize (c, base) && @@ -373,7 +380,8 @@ struct CmapSubtableFormat14 return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && record.sanitize (c, this)); @@ -418,7 +426,8 @@ struct CmapSubtable } } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); if (!u.format.sanitize (c)) return TRACE_RETURN (false); switch (u.format) { @@ -461,7 +470,8 @@ struct EncodingRecord return 0; } - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && subtable.sanitize (c, base)); @@ -496,7 +506,8 @@ struct cmap return &(this+encodingRecord[result].subtable); } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (version == 0) && diff --git a/src/hb-ot-head-table.hh b/src/hb-ot-head-table.hh index ec4e8c9d4..268f13340 100644 --- a/src/hb-ot-head-table.hh +++ b/src/hb-ot-head-table.hh @@ -45,13 +45,15 @@ struct head { static const hb_tag_t tableTag = HB_OT_TAG_head; - inline unsigned int get_upem (void) const { + inline unsigned int get_upem (void) const + { unsigned int upem = unitsPerEm; /* If no valid head table found, assume 1000, which matches typical Type1 usage. */ return 16 <= upem && upem <= 16384 ? upem : 1000; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); } diff --git a/src/hb-ot-hhea-table.hh b/src/hb-ot-hhea-table.hh index edc0e29cb..992fe5520 100644 --- a/src/hb-ot-hhea-table.hh +++ b/src/hb-ot-hhea-table.hh @@ -49,7 +49,8 @@ struct _hea static const hb_tag_t hheaTag = HB_OT_TAG_hhea; static const hb_tag_t vheaTag = HB_OT_TAG_vhea; - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); } diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 317854ce7..a0e3855a8 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -57,7 +57,8 @@ struct _mtx static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx; static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx; - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); /* We don't check for anything specific here. The users of the * struct do all the hard work... */ diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index abd063c89..2eaa609f9 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -63,9 +63,10 @@ struct Record struct sanitize_closure_t { hb_tag_t tag; - void *list_base; + const void *list_base; }; - inline bool sanitize (hb_sanitize_context_t *c, void *base) { + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { TRACE_SANITIZE (this); const sanitize_closure_t closure = {tag, base}; return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure)); @@ -121,7 +122,8 @@ struct RecordListOf : RecordArrayOf inline const Type& operator [] (unsigned int i) const { return this+RecordArrayOf::operator [](i).offset; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (RecordArrayOf::sanitize (c, this)); } @@ -134,7 +136,8 @@ struct RangeRecord return g < start ? -1 : g <= end ? 0 : +1 ; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this)); } @@ -199,7 +202,8 @@ struct LangSys } inline bool sanitize (hb_sanitize_context_t *c, - const Record::sanitize_closure_t * = NULL) { + const Record::sanitize_closure_t * = NULL) const + { TRACE_SANITIZE (this); return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); } @@ -238,7 +242,8 @@ struct Script inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } inline bool sanitize (hb_sanitize_context_t *c, - const Record