src/hb-dsalgs.hh | 14 +-- src/hb-open-file.hh | 214 +++++++++++++++++++++--------------------------- src/hb-open-type.hh | 81 +++++++++++------- src/hb-ot-post-table.hh | 2 4 files changed, 157 insertions(+), 154 deletions(-)
New commits: commit 180a88a96ce327e4103df3635c73559de65d1546 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 19:19:57 2018 +0200 [dfont] Some more diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 89b76d82..5c653fed 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -322,7 +322,8 @@ struct ResourceRecord struct ResourceTypeRecord { - inline unsigned int get_resource_count (void) const { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; } + inline unsigned int get_resource_count (void) const + { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; } inline bool is_sfnt (void) const { return tag == HB_TAG_sfnt; } @@ -363,14 +364,6 @@ struct ResourceMap get_type_count ()) [i]; } - inline unsigned int get_type_count (void) const { return typeCountM1 + 1; } - - inline const ResourceRecord &get_resource_record (const ResourceTypeRecord &type, - unsigned int i) const - { - return type.get_resource_record (i, &(this+typeListZ)); - } - inline unsigned int get_face_count (void) const { unsigned int count = get_type_count (); @@ -390,11 +383,10 @@ struct ResourceMap for (unsigned int i = 0; i < count; i++) { const ResourceTypeRecord& type = get_type_record (i); + /* The check for idx < count is here because ResourceRecord is NOT null-safe. + * Because an offset of 0 there does NOT mean null. */ if (type.is_sfnt () && idx < type.get_resource_count ()) - { - const OpenTypeFontFace &face = get_resource_record (type, idx).get_face (data_base); - return face; - } + return type.get_resource_record (idx, &(this+typeListZ)).get_face (data_base); } return Null (OpenTypeFontFace); } @@ -410,6 +402,9 @@ struct ResourceMap data_base)); } + private: + inline unsigned int get_type_count (void) const { return typeCountM1 + 1; } + protected: HBUINT8 reserved0[16]; /* Reserved for copy of resource header */ HBUINT32 reserved1; /* Reserved for handle to next resource map */ commit 0ab0f1e5ac5ccb07c57364e9f5be0b991398eb6f Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 19:13:01 2018 +0200 [dfont] Push methods further down diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 0c669119..89b76d82 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -371,6 +371,34 @@ struct ResourceMap return type.get_resource_record (i, &(this+typeListZ)); } + inline unsigned int get_face_count (void) const + { + unsigned int count = get_type_count (); + for (unsigned int i = 0; i < count; i++) + { + const ResourceTypeRecord& type = get_type_record (i); + if (type.is_sfnt ()) + return type.get_resource_count (); + } + return 0; + } + + inline const OpenTypeFontFace& get_face (unsigned int idx, + const void *data_base) const + { + unsigned int count = get_type_count (); + for (unsigned int i = 0; i < count; i++) + { + const ResourceTypeRecord& type = get_type_record (i); + if (type.is_sfnt () && idx < type.get_resource_count ()) + { + const OpenTypeFontFace &face = get_resource_record (type, idx).get_face (data_base); + return face; + } + } + return Null (OpenTypeFontFace); + } + inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const { TRACE_SANITIZE (this); @@ -400,35 +428,15 @@ struct ResourceMap struct ResourceForkHeader { inline unsigned int get_face_count (void) const - { - const ResourceMap &resource_map = this+map; - unsigned int count = resource_map.get_type_count (); - for (unsigned int i = 0; i < count; i++) - { - const ResourceTypeRecord& type = resource_map.get_type_record (i); - if (type.is_sfnt ()) - return type.get_resource_count (); - } - return 0; - } + { return (this+map).get_face_count (); } inline const OpenTypeFontFace& get_face (unsigned int idx, unsigned int *base_offset = nullptr) const { - const ResourceMap &resource_map = this+map; - unsigned int count = resource_map.get_type_count (); - for (unsigned int i = 0; i < count; i++) - { - const ResourceTypeRecord& type = resource_map.get_type_record (i); - if (type.is_sfnt () && idx < type.get_resource_count ()) - { - const OpenTypeFontFace &face = resource_map.get_resource_record (type, idx).get_face (&(this+data)); - if (base_offset) - *base_offset = (const char *) &face - (const char *) this; - return face; - } - } - return Null (OpenTypeFontFace); + const OpenTypeFontFace &face = (this+map).get_face (idx, &(this+data)); + if (base_offset) + *base_offset = (const char *) &face - (const char *) this; + return face; } inline bool sanitize (hb_sanitize_context_t *c) const commit 8c9bdcc1feeab321a642bdaac50b716e48ce4263 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 19:08:22 2018 +0200 [dfont] Minor diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index ce39bfc9..0c669119 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -322,9 +322,9 @@ struct ResourceRecord struct ResourceTypeRecord { - inline unsigned int get_resource_count () const { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; } + inline unsigned int get_resource_count (void) const { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; } - inline bool is_sfnt () const { return tag == HB_TAG_sfnt; } + inline bool is_sfnt (void) const { return tag == HB_TAG_sfnt; } inline const ResourceRecord& get_resource_record (unsigned int i, const void *type_base) const @@ -363,7 +363,7 @@ struct ResourceMap get_type_count ()) [i]; } - inline unsigned int get_type_count () const { return typeCountM1 + 1; } + inline unsigned int get_type_count (void) const { return typeCountM1 + 1; } inline const ResourceRecord &get_resource_record (const ResourceTypeRecord &type, unsigned int i) const @@ -399,7 +399,7 @@ struct ResourceMap struct ResourceForkHeader { - inline unsigned int get_face_count () const + inline unsigned int get_face_count (void) const { const ResourceMap &resource_map = this+map; unsigned int count = resource_map.get_type_count (); commit 4479d3a2eda57d278700f5c78414ef6ef617d2a9 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 19:05:59 2018 +0200 [dfon]t Sanitize OpenTypeFontFace diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 692002e9..eb15c089 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -537,12 +537,6 @@ struct hb_bytes_t inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } - template <typename Type> - inline const Type* as (void) const - { - return unlikely (!arrayZ) ? &Null(Type) : reinterpret_cast<const Type *> (arrayZ); - } - inline int cmp (const hb_bytes_t &a) const { if (len != a.len) diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 92dca3f8..ce39bfc9 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -293,15 +293,16 @@ struct TTCHeader struct ResourceRecord { - inline const hb_bytes_t get_data (const void *data_base) const - { return hb_bytes_t (data_base+offset); } + inline const OpenTypeFontFace & get_face (const void *data_base) const + { return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); } inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - offset.sanitize (c, data_base)); + offset.sanitize (c, data_base) && + get_face (data_base).sanitize (c)); } protected: @@ -317,11 +318,13 @@ struct ResourceRecord DEFINE_SIZE_STATIC (12); }; +#define HB_TAG_sfnt HB_TAG ('s','f','n','t') + struct ResourceTypeRecord { - inline unsigned int get_resource_count () const { return resCountM1 + 1; } + inline unsigned int get_resource_count () const { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; } - inline bool is_sfnt () const { return tag == HB_TAG ('s','f','n','t'); } + inline bool is_sfnt () const { return tag == HB_TAG_sfnt; } inline const ResourceRecord& get_resource_record (unsigned int i, const void *type_base) const @@ -409,10 +412,6 @@ struct ResourceForkHeader return 0; } - inline const hb_bytes_t get_data (const ResourceTypeRecord& type, - unsigned int idx) const - { return (this+map).get_resource_record (type, idx).get_data (&(this+data)); } - inline const OpenTypeFontFace& get_face (unsigned int idx, unsigned int *base_offset = nullptr) const { @@ -423,7 +422,7 @@ struct ResourceForkHeader const ResourceTypeRecord& type = resource_map.get_type_record (i); if (type.is_sfnt () && idx < type.get_resource_count ()) { - const OpenTypeFontFace &face = *get_data (type, idx).as<OpenTypeFontFace> (); + const OpenTypeFontFace &face = resource_map.get_resource_record (type, idx).get_face (&(this+data)); if (base_offset) *base_offset = (const char *) &face - (const char *) this; return face; @@ -437,8 +436,6 @@ struct ResourceForkHeader TRACE_SANITIZE (this); return_trace (c->check_struct (this) && map.sanitize (c, this, &(this+data))); - - // XXX Sanitize OpenTypeFontFace's } protected: commit 3fba41906fba28c5ea01cc0749654de862453bf4 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 18:49:16 2018 +0200 [dfont] Minor diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index b960d62d..92dca3f8 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -411,17 +411,14 @@ struct ResourceForkHeader inline const hb_bytes_t get_data (const ResourceTypeRecord& type, unsigned int idx) const - { - const ResourceMap &resource_map = this+map; - const void *data_base = &(this+data); - return resource_map.get_resource_record (type, idx).get_data (data_base); - } + { return (this+map).get_resource_record (type, idx).get_data (&(this+data)); } inline const OpenTypeFontFace& get_face (unsigned int idx, unsigned int *base_offset = nullptr) const { const ResourceMap &resource_map = this+map; - for (unsigned int i = 0; i < resource_map.get_type_count (); i++) + unsigned int count = resource_map.get_type_count (); + for (unsigned int i = 0; i < count; i++) { const ResourceTypeRecord& type = resource_map.get_type_record (i); if (type.is_sfnt () && idx < type.get_resource_count ()) commit bf852f0e62a8bdbb809af6a975f8ae8eed708d70 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 18:47:53 2018 +0200 [dfont] Make test pass Offset 0 is not null in this context. diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index d3e87225..b960d62d 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -309,7 +309,7 @@ struct ResourceRecord HBINT16 nameOffset; /* Offset from beginning of resource name list * to resource name, -1 means there is none. */ HBUINT8 attrs; /* Resource attributes */ - OffsetTo<LArrayOf<HBUINT8>, HBUINT24> + OffsetTo<LArrayOf<HBUINT8>, HBUINT24, false> offset; /* Offset from beginning of data block to * data for this resource */ HBUINT32 reserved; /* Reserved for handle to resource */ commit 29faebe911a13916aa3d737e93d38deedc53567f Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 18:45:35 2018 +0200 Allow Offset<>'s that have no 0==null diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 973dc5e1..b10d33b1 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -155,10 +155,10 @@ struct Index : HBUINT16 { DECLARE_NULL_NAMESPACE_BYTES (OT, Index); /* Offset, Null offset = 0 */ -template <typename Type> +template <typename Type, bool has_null=true> struct Offset : Type { - inline bool is_null (void) const { return 0 == *this; } + inline bool is_null (void) const { return has_null && 0 == *this; } inline void *serialize (hb_serialize_context_t *c, const void *base) { @@ -226,20 +226,18 @@ struct FixedVersion * Use: (base+offset) */ -template <typename Type, typename OffsetType=HBUINT16> -struct OffsetTo : Offset<OffsetType> +template <typename Type, typename OffsetType=HBUINT16, bool has_null=true> +struct OffsetTo : Offset<OffsetType, has_null> { inline const Type& operator () (const void *base) const { - unsigned int offset = *this; - if (unlikely (!offset)) return Null(Type); - return StructAtOffset<const Type> (base, offset); + if (unlikely (this->is_null ())) return Null(Type); + return StructAtOffset<const Type> (base, *this); } inline Type& operator () (void *base) const { - unsigned int offset = *this; - if (unlikely (!offset)) return Crap(Type); - return StructAtOffset<Type> (base, offset); + if (unlikely (this->is_null ())) return Crap(Type); + return StructAtOffset<Type> (base, *this); } inline Type& serialize (hb_serialize_context_t *c, const void *base) @@ -264,9 +262,8 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); - unsigned int offset = *this; - if (unlikely (!offset)) return_trace (true); - if (unlikely (!c->check_range (base, offset))) return_trace (false); + if (unlikely (this->is_null ())) return_trace (true); + if (unlikely (!c->check_range (base, *this))) return_trace (false); return_trace (true); } @@ -274,7 +271,7 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (!*this || + (this->is_null () || StructAtOffset<Type> (base, *this).sanitize (c) || neuter (c))); } @@ -283,7 +280,7 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (!*this || + (this->is_null () || StructAtOffset<Type> (base, *this).sanitize (c, d1) || neuter (c))); } @@ -292,7 +289,7 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (!*this || + (this->is_null () || StructAtOffset<Type> (base, *this).sanitize (c, d1, d2) || neuter (c))); } @@ -301,22 +298,24 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (!*this || + (this->is_null () || StructAtOffset<Type> (base, *this).sanitize (c, d1, d2, d3) || neuter (c))); } /* Set the offset to Null */ - inline bool neuter (hb_sanitize_context_t *c) const { + inline bool neuter (hb_sanitize_context_t *c) const + { + if (!has_null) return false; return c->try_set (this, 0); } DEFINE_SIZE_STATIC (sizeof(OffsetType)); }; template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {}; -template <typename Base, typename OffsetType, typename Type> -static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); } -template <typename Base, typename OffsetType, typename Type> -static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); } +template <typename Base, typename OffsetType, bool has_null, typename Type> +static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); } +template <typename Base, typename OffsetType, bool has_null, typename Type> +static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); } /* commit 82f4d776c21b7c1224dd7073ce69cdf76d85f16b Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 18:27:20 2018 +0200 [dfont] Minor diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 5cff0806..d3e87225 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -305,7 +305,7 @@ struct ResourceRecord } protected: - HBUINT16 id; /* Resource ID, is really should be signed? */ + HBUINT16 id; /* Resource ID. */ HBINT16 nameOffset; /* Offset from beginning of resource name list * to resource name, -1 means there is none. */ HBUINT8 attrs; /* Resource attributes */ @@ -400,7 +400,7 @@ struct ResourceForkHeader { const ResourceMap &resource_map = this+map; unsigned int count = resource_map.get_type_count (); - for (unsigned int i = 0; i < count; ++i) + for (unsigned int i = 0; i < count; i++) { const ResourceTypeRecord& type = resource_map.get_type_record (i); if (type.is_sfnt ()) @@ -421,7 +421,7 @@ struct ResourceForkHeader unsigned int *base_offset = nullptr) const { const ResourceMap &resource_map = this+map; - for (unsigned int i = 0; i < resource_map.get_type_count (); ++i) + for (unsigned int i = 0; i < resource_map.get_type_count (); i++) { const ResourceTypeRecord& type = resource_map.get_type_record (i); if (type.is_sfnt () && idx < type.get_resource_count ()) commit 07e0ca930c29757217c2f9e4e0e6954657b6b82d Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 17:39:09 2018 +0200 [bytes] Rename content to arrayZ diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 26e8e42a..692002e9 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -529,18 +529,18 @@ struct hb_array_t struct hb_bytes_t { - inline hb_bytes_t (void) : bytes (nullptr), len (0) {} - inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {} - inline hb_bytes_t (const void *bytes_, unsigned int len_) : bytes ((const char *) bytes_), len (len_) {} + inline hb_bytes_t (void) : arrayZ (nullptr), len (0) {} + inline hb_bytes_t (const char *bytes_, unsigned int len_) : arrayZ (bytes_), len (len_) {} + inline hb_bytes_t (const void *bytes_, unsigned int len_) : arrayZ ((const char *) bytes_), len (len_) {} template <typename T> - inline hb_bytes_t (const T& array) : bytes ((const char *) array.arrayZ), len (array.len) {} + inline hb_bytes_t (const T& array) : arrayZ ((const char *) array.arrayZ), len (array.len) {} - inline void free (void) { ::free ((void *) bytes); bytes = nullptr; len = 0; } + inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } template <typename Type> inline const Type* as (void) const { - return unlikely (!bytes) ? &Null(Type) : reinterpret_cast<const Type *> (bytes); + return unlikely (!arrayZ) ? &Null(Type) : reinterpret_cast<const Type *> (arrayZ); } inline int cmp (const hb_bytes_t &a) const @@ -548,7 +548,7 @@ struct hb_bytes_t if (len != a.len) return (int) a.len - (int) len; - return memcmp (a.bytes, bytes, len); + return memcmp (a.arrayZ, arrayZ, len); } static inline int cmp (const void *pa, const void *pb) { @@ -557,7 +557,7 @@ struct hb_bytes_t return b->cmp (*a); } - const char *bytes; + const char *arrayZ; unsigned int len; }; diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index 29dc86fa..5f27fd50 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -143,7 +143,7 @@ struct post return true; if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */ return false; - strncpy (buf, s.bytes, s.len); + strncpy (buf, s.arrayZ, s.len); buf[s.len] = '\0'; return true; } commit dbb764dceb61365b7360a48d581ba5a4b3526e98 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 16:49:26 2018 +0200 [dfont] Clean up sanitize() I don't think I broke anything. Fuzzers will let me know.. diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index def968eb..26e8e42a 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -532,9 +532,17 @@ struct hb_bytes_t inline hb_bytes_t (void) : bytes (nullptr), len (0) {} inline hb_bytes_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {} inline hb_bytes_t (const void *bytes_, unsigned int len_) : bytes ((const char *) bytes_), len (len_) {} + template <typename T> + inline hb_bytes_t (const T& array) : bytes ((const char *) array.arrayZ), len (array.len) {} inline void free (void) { ::free ((void *) bytes); bytes = nullptr; len = 0; } + template <typename Type> + inline const Type* as (void) const + { + return unlikely (!bytes) ? &Null(Type) : reinterpret_cast<const Type *> (bytes); + } + inline int cmp (const hb_bytes_t &a) const { if (len != a.len) diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 26e68bb5..5cff0806 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -293,18 +293,24 @@ struct TTCHeader struct ResourceRecord { - inline bool sanitize (hb_sanitize_context_t *c) const + inline const hb_bytes_t get_data (const void *data_base) const + { return hb_bytes_t (data_base+offset); } + + inline bool sanitize (hb_sanitize_context_t *c, + const void *data_base) const { TRACE_SANITIZE (this); - // actual data sanitization is done on ResourceForkHeader sanitizer - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this) && + offset.sanitize (c, data_base)); } + protected: HBUINT16 id; /* Resource ID, is really should be signed? */ HBINT16 nameOffset; /* Offset from beginning of resource name list * to resource name, -1 means there is none. */ HBUINT8 attrs; /* Resource attributes */ - HBUINT24 dataOffset; /* Offset from beginning of resource data to + OffsetTo<LArrayOf<HBUINT8>, HBUINT24> + offset; /* Offset from beginning of data block to * data for this resource */ HBUINT32 reserved; /* Reserved for handle to resource */ public: @@ -313,28 +319,33 @@ struct ResourceRecord struct ResourceTypeRecord { - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - // RefList sanitization is done on ResourceMap sanitizer - return_trace (likely (c->check_struct (this))); - } - inline unsigned int get_resource_count () const { return resCountM1 + 1; } inline bool is_sfnt () const { return tag == HB_TAG ('s','f','n','t'); } - inline const ResourceRecord& get_resource_record (const void *base, - unsigned int i) const + inline const ResourceRecord& get_resource_record (unsigned int i, + const void *type_base) const { - return (base+refList)[i]; + return hb_array_t<ResourceRecord> ((type_base+resourcesZ).arrayZ, + get_resource_count ()) [i]; + } + + inline bool sanitize (hb_sanitize_context_t *c, + const void *type_base, + const void *data_base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + resourcesZ.sanitize (c, type_base, + get_resource_count (), + data_base)); } protected: Tag tag; /* Resource type. */ HBUINT16 resCountM1; /* Number of resources minus 1. */ OffsetTo<UnsizedArrayOf<ResourceRecord> > - refList; /* Offset from beginning of resource type list + resourcesZ; /* Offset from beginning of resource type list * to reference item list for this type. */ public: DEFINE_SIZE_STATIC (8); @@ -342,35 +353,30 @@ struct ResourceTypeRecord struct ResourceMap { - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); - for (unsigned int i = 0; i < get_types_count (); ++i) - { - const ResourceTypeRecord& type = get_type_record (i); - if (unlikely (!type.sanitize (c))) - return_trace (false); - for (unsigned int j = 0; j < type.get_resource_count (); ++j) - if (unlikely (!get_resource_record (type, j).sanitize (c))) - return_trace (false); - } - return_trace (true); - } - inline const ResourceTypeRecord& get_type_record (unsigned int i) const { // Why offset from the third byte of the object? I'm not sure - return (((const char *) this + 2)+typeListZ)[i]; + return hb_array_t<ResourceTypeRecord> (((2 + (const char *) this )+typeListZ).arrayZ, + get_type_count ()) [i]; } - inline unsigned int get_types_count () const { return typeCountM1 + 1; } + inline unsigned int get_type_count () const { return typeCountM1 + 1; } inline const ResourceRecord &get_resource_record (const ResourceTypeRecord &type, unsigned int i) const { - return type.get_resource_record (&(this+typeListZ), i); + return type.get_resource_record (i, &(this+typeListZ)); + } + + inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const + { + TRACE_SANITIZE (this); + const void *type_base = &(this+typeListZ); + return_trace (c->check_struct (this) && + typeListZ.sanitize (c, 2 + (const char *) this, + get_type_count (), + type_base, + data_base)); } protected: @@ -393,7 +399,8 @@ struct ResourceForkHeader inline unsigned int get_face_count () const { const ResourceMap &resource_map = this+map; - for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) + unsigned int count = resource_map.get_type_count (); + for (unsigned int i = 0; i < count; ++i) { const ResourceTypeRecord& type = resource_map.get_type_record (i); if (type.is_sfnt ()) @@ -402,23 +409,24 @@ struct ResourceForkHeader return 0; } - inline const LArrayOf<HBUINT8>& get_data (const ResourceTypeRecord& type, - unsigned int idx) const + inline const hb_bytes_t get_data (const ResourceTypeRecord& type, + unsigned int idx) const { const ResourceMap &resource_map = this+map; - unsigned int offset = dataOffset + resource_map.get_resource_record (type, idx).dataOffset; - return StructAtOffset<LArrayOf<HBUINT8> > (this, offset); + const void *data_base = &(this+data); + return resource_map.get_resource_record (type, idx).get_data (data_base); } - inline const OpenTypeFontFace& get_face (unsigned int idx, unsigned int *base_offset = nullptr) const + inline const OpenTypeFontFace& get_face (unsigned int idx, + unsigned int *base_offset = nullptr) const { const ResourceMap &resource_map = this+map; - for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) + for (unsigned int i = 0; i < resource_map.get_type_count (); ++i) { const ResourceTypeRecord& type = resource_map.get_type_record (i); if (type.is_sfnt () && idx < type.get_resource_count ()) { - const OpenTypeFontFace &face = (OpenTypeFontFace&) get_data (type, idx).arrayZ; + const OpenTypeFontFace &face = *get_data (type, idx).as<OpenTypeFontFace> (); if (base_offset) *base_offset = (const char *) &face - (const char *) this; return face; @@ -430,33 +438,15 @@ struct ResourceForkHeader inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); - - const ResourceMap &resource_map = this+map; - if (unlikely (!resource_map.sanitize (c))) - return_trace (false); + return_trace (c->check_struct (this) && + map.sanitize (c, this, &(this+data))); - for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) - { - const ResourceTypeRecord& type = resource_map.get_type_record (i); - for (unsigned int j = 0; j < type.get_resource_count (); ++j) - { - const LArrayOf<HBUINT8>& data = get_data (type, j); - if (unlikely (!data.sanitize (c))) - return_trace (false); - - if (unlikely (type.is_sfnt () && - !((OpenTypeFontFace&) data.arrayZ).sanitize (c))) - return_trace (false); - } - } - - return_trace (true); + // XXX Sanitize OpenTypeFontFace's } protected: - Offset32 dataOffset; /* Offset from beginning of resource fork + LOffsetTo<UnsizedArrayOf<HBUINT8> > + data; /* Offset from beginning of resource fork * to resource data */ LOffsetTo<ResourceMap> map; /* Offset from beginning of resource fork commit 361fc2686152ad8c0ebaf19e0522e0fc58ba3953 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 16:47:33 2018 +0200 Fix OffsetTo::sanitize() after reshuffling diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 3926694b..973dc5e1 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -274,7 +274,8 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (StructAtOffset<Type> (base, *this).sanitize (c) || + (!*this || + StructAtOffset<Type> (base, *this).sanitize (c) || neuter (c))); } template <typename T1> @@ -282,7 +283,8 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (StructAtOffset<Type> (base, *this).sanitize (c, d1) || + (!*this || + StructAtOffset<Type> (base, *this).sanitize (c, d1) || neuter (c))); } template <typename T1, typename T2> @@ -290,7 +292,8 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (StructAtOffset<Type> (base, *this).sanitize (c, d1, d2) || + (!*this || + StructAtOffset<Type> (base, *this).sanitize (c, d1, d2) || neuter (c))); } template <typename T1, typename T2, typename T3> @@ -298,7 +301,8 @@ struct OffsetTo : Offset<OffsetType> { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (StructAtOffset<Type> (base, *this).sanitize (c, d1, d2, d3) || + (!*this || + StructAtOffset<Type> (base, *this).sanitize (c, d1, d2, d3) || neuter (c))); } commit 4c6b0fb5f6668a6e562260d16f629ad3c41e8961 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 16:39:30 2018 +0200 OffsetTo::sanitize() Add version with three user_data diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 76ce55a7..3926694b 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -277,20 +277,28 @@ struct OffsetTo : Offset<OffsetType> (StructAtOffset<Type> (base, *this).sanitize (c) || neuter (c))); } - template <typename T> - inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + template <typename T1> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (StructAtOffset<Type> (base, *this).sanitize (c, user_data) || + (StructAtOffset<Type> (base, *this).sanitize (c, d1) || neuter (c))); } template <typename T1, typename T2> - inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 user_data1, T2 user_data2) const + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2) const + { + TRACE_SANITIZE (this); + return_trace (sanitize_shallow (c, base) && + (StructAtOffset<Type> (base, *this).sanitize (c, d1, d2) || + neuter (c))); + } + template <typename T1, typename T2, typename T3> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2, T3 d3) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && - (StructAtOffset<Type> (base, *this).sanitize (c, user_data1, user_data2) || + (StructAtOffset<Type> (base, *this).sanitize (c, d1, d2, d3) || neuter (c))); } commit a73bea69c599787b4cfeac92a3afd00749e00434 Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 16:31:31 2018 +0200 OffsetTo::sanitize() more shuffling diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 2c71f819..76ce55a7 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -273,25 +273,25 @@ struct OffsetTo : Offset<OffsetType> inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, base))) return_trace (false); - const Type &obj = StructAtOffset<Type> (base, *this); - return_trace (likely (obj.sanitize (c)) || neuter (c)); + return_trace (sanitize_shallow (c, base) && + (StructAtOffset<Type> (base, *this).sanitize (c) || + neuter (c))); } template <typename T> inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, base))) return_trace (false); - const Type &obj = StructAtOffset<Type> (base, *this); - return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); + return_trace (sanitize_shallow (c, base) && + (StructAtOffset<Type> (base, *this).sanitize (c, user_data) || + neuter (c))); } template <typename T1, typename T2> inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 user_data1, T2 user_data2) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, base))) return_trace (false); - const Type &obj = StructAtOffset<Type> (base, *this); - return_trace (likely (obj.sanitize (c, user_data1, user_data2)) || neuter (c)); + return_trace (sanitize_shallow (c, base) && + (StructAtOffset<Type> (base, *this).sanitize (c, user_data1, user_data2) || + neuter (c))); } /* Set the offset to Null */ commit b482e5231cd5987082dd2c05fd649c3653f3c67a Author: Behdad Esfahbod <[email protected]> Date: Thu Sep 13 16:29:49 2018 +0200 OffsetTo::sanitize() reshuffling diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 5d09c520..2c71f819 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -260,27 +260,39 @@ struct OffsetTo : Offset<OffsetType> this->set (0); } - inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + inline bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; if (unlikely (!offset)) return_trace (true); if (unlikely (!c->check_range (base, offset))) return_trace (false); - const Type &obj = StructAtOffset<Type> (base, offset); + return_trace (true); + } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c, base))) return_trace (false); + const Type &obj = StructAtOffset<Type> (base, *this); return_trace (likely (obj.sanitize (c)) || neuter (c)); } template <typename T> 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 (false); - unsigned int offset = *this; - if (unlikely (!offset)) return_trace (true); - if (unlikely (!c->check_range (base, offset))) return_trace (false); - const Type &obj = StructAtOffset<Type> (base, offset); + if (unlikely (!sanitize_shallow (c, base))) return_trace (false); + const Type &obj = StructAtOffset<Type> (base, *this); return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); } + template <typename T1, typename T2> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T1 user_data1, T2 user_data2) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c, base))) return_trace (false); + const Type &obj = StructAtOffset<Type> (base, *this); + return_trace (likely (obj.sanitize (c, user_data1, user_data2)) || neuter (c)); + } /* Set the offset to Null */ inline bool neuter (hb_sanitize_context_t *c) const { commit bd75fd45cdbd0edb24568326bb7fde59d299a82c Author: Behdad Esfahbod <[email protected]> Date: Tue Sep 11 18:12:26 2018 +0200 [dfont] Some renaming, plus add link to reference doc diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index bbfc8f0e..26e68bb5 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -287,9 +287,11 @@ struct TTCHeader /* * Mac Resource Fork + * + * http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html */ -struct ResourceRefItem +struct ResourceRecord { inline bool sanitize (hb_sanitize_context_t *c) const { @@ -298,10 +300,10 @@ struct ResourceRefItem return_trace (likely (c->check_struct (this))); } - HBINT16 id; /* Resource ID, is really should be signed? */ + HBUINT16 id; /* Resource ID, is really should be signed? */ HBINT16 nameOffset; /* Offset from beginning of resource name list * to resource name, -1 means there is none. */ - HBUINT8 attr; /* Resource attributes */ + HBUINT8 attrs; /* Resource attributes */ HBUINT24 dataOffset; /* Offset from beginning of resource data to * data for this resource */ HBUINT32 reserved; /* Reserved for handle to resource */ @@ -309,7 +311,7 @@ struct ResourceRefItem DEFINE_SIZE_STATIC (12); }; -struct ResourceTypeItem +struct ResourceTypeRecord { inline bool sanitize (hb_sanitize_context_t *c) const { @@ -318,20 +320,20 @@ struct ResourceTypeItem return_trace (likely (c->check_struct (this))); } - inline unsigned int get_resource_count () const { return numRes + 1; } + inline unsigned int get_resource_count () const { return resCountM1 + 1; } - inline bool is_sfnt () const { return type == HB_TAG ('s','f','n','t'); } + inline bool is_sfnt () const { return tag == HB_TAG ('s','f','n','t'); } - inline const ResourceRefItem& get_ref_item (const void *base, - unsigned int i) const + inline const ResourceRecord& get_resource_record (const void *base, + unsigned int i) const { return (base+refList)[i]; } protected: - Tag type; /* Resource type. */ - HBUINT16 numRes; /* Number of resources minus 1. */ - OffsetTo<UnsizedArrayOf<ResourceRefItem> > + Tag tag; /* Resource type. */ + HBUINT16 resCountM1; /* Number of resources minus 1. */ + OffsetTo<UnsizedArrayOf<ResourceRecord> > refList; /* Offset from beginning of resource type list * to reference item list for this type. */ public: @@ -347,51 +349,41 @@ struct ResourceMap return_trace (false); for (unsigned int i = 0; i < get_types_count (); ++i) { - const ResourceTypeItem& type = get_type (i); + const ResourceTypeRecord& type = get_type_record (i); if (unlikely (!type.sanitize (c))) return_trace (false); for (unsigned int j = 0; j < type.get_resource_count (); ++j) - if (unlikely (!get_ref_item (type, j).sanitize (c))) + if (unlikely (!get_resource_record (type, j).sanitize (c))) return_trace (false); } return_trace (true); } - inline const ResourceTypeItem& get_type (unsigned int i) const + inline const ResourceTypeRecord& get_type_record (unsigned int i) const { - // Why offset from the second byte of the object? I'm not sure - return ((&reserved[2])+typeList)[i]; + // Why offset from the third byte of the object? I'm not sure + return (((const char *) this + 2)+typeListZ)[i]; } - inline unsigned int get_types_count () const { return nTypes + 1; } - - inline const ResourceRefItem &get_ref_item (const ResourceTypeItem &type, - unsigned int i) const - { - return type.get_ref_item (&(this+typeList), i); - } + inline unsigned int get_types_count () const { return typeCountM1 + 1; } - inline const PString& get_name (const ResourceRefItem &item, - unsigned int i) const + inline const ResourceRecord &get_resource_record (const ResourceTypeRecord &type, + unsigned int i) const { - if (item.nameOffset < 0) - return Null (PString); - - return StructAtOffset<PString> (this, nameList + item.nameOffset); + return type.get_resource_record (&(this+typeListZ), i); } protected: - HBUINT8 reserved[16]; /* Reserved for copy of resource header */ - LOffsetTo<ResourceMap> - reserved1; /* Reserved for handle to next resource map */ - HBUINT16 reserved2; /* Reserved for file reference number */ - HBUINT16 attr; /* Resource fork attribute */ - OffsetTo<UnsizedArrayOf<ResourceTypeItem> > - typeList; /* Offset from beginning of map to + HBUINT8 reserved0[16]; /* Reserved for copy of resource header */ + HBUINT32 reserved1; /* Reserved for handle to next resource map */ + HBUINT16 resreved2; /* Reserved for file reference number */ + HBUINT16 attrs; /* Resource fork attribute */ + OffsetTo<UnsizedArrayOf<ResourceTypeRecord> > + typeListZ; /* Offset from beginning of map to * resource type list */ Offset16 nameList; /* Offset from beginning of map to * resource name list */ - HBUINT16 nTypes; /* Number of types in the map minus 1 */ + HBUINT16 typeCountM1; /* Number of types in the map minus 1 */ public: DEFINE_SIZE_STATIC (30); }; @@ -403,19 +395,18 @@ struct ResourceForkHeader const ResourceMap &resource_map = this+map; for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) { - const ResourceTypeItem& type = resource_map.get_type (i); + const ResourceTypeRecord& type = resource_map.get_type_record (i); if (type.is_sfnt ()) return type.get_resource_count (); } return 0; } - inline const LArrayOf<HBUINT8>& get_data (const ResourceTypeItem& type, + inline const LArrayOf<HBUINT8>& get_data (const ResourceTypeRecord& type, unsigned int idx) const { const ResourceMap &resource_map = this+map; - unsigned int offset = dataOffset; - offset += resource_map.get_ref_item (type, idx).dataOffset; + unsigned int offset = dataOffset + resource_map.get_resource_record (type, idx).dataOffset; return StructAtOffset<LArrayOf<HBUINT8> > (this, offset); } @@ -424,7 +415,7 @@ struct ResourceForkHeader const ResourceMap &resource_map = this+map; for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) { - const ResourceTypeItem& type = resource_map.get_type (i); + const ResourceTypeRecord& type = resource_map.get_type_record (i); if (type.is_sfnt () && idx < type.get_resource_count ()) { const OpenTypeFontFace &face = (OpenTypeFontFace&) get_data (type, idx).arrayZ; @@ -448,7 +439,7 @@ struct ResourceForkHeader for (unsigned int i = 0; i < resource_map.get_types_count (); ++i) { - const ResourceTypeItem& type = resource_map.get_type (i); + const ResourceTypeRecord& type = resource_map.get_type_record (i); for (unsigned int j = 0; j < type.get_resource_count (); ++j) { const LArrayOf<HBUINT8>& data = get_data (type, j); @@ -465,7 +456,7 @@ struct ResourceForkHeader } protected: - HBUINT32 dataOffset; /* Offset from beginning of resource fork + Offset32 dataOffset; /* Offset from beginning of resource fork * to resource data */ LOffsetTo<ResourceMap> map; /* Offset from beginning of resource fork commit 4134ec1307bbaff24972e238bc5e4a403cd3f1c1 Author: Behdad Esfahbod <[email protected]> Date: Tue Sep 11 17:56:03 2018 +0200 [dfont] Sanitize only sfnt resources as OpenTypeFontFile diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 35a774dd..bbfc8f0e 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -300,7 +300,7 @@ struct ResourceRefItem HBINT16 id; /* Resource ID, is really should be signed? */ HBINT16 nameOffset; /* Offset from beginning of resource name list - * to resource name, minus means there is none. */ + * to resource name, -1 means there is none. */ HBUINT8 attr; /* Resource attributes */ HBUINT24 dataOffset; /* Offset from beginning of resource data to * data for this resource */ @@ -374,7 +374,7 @@ struct ResourceMap inline const PString& get_name (const ResourceRefItem &item, unsigned int i) const { - if (item.nameOffset == -1) + if (item.nameOffset < 0) return Null (PString); return StructAtOffset<PString> (this, nameList + item.nameOffset); @@ -452,8 +452,11 @@ struct ResourceForkHeader for (unsigned int j = 0; j < type.get_resource_count (); ++j) { const LArrayOf<HBUINT8>& data = get_data (type, j); - if (unlikely (!(data.sanitize (c) && - ((OpenTypeFontFace&) data.arrayZ).sanitize (c)))) + if (unlikely (!data.sanitize (c))) + return_trace (false); + + if (unlikely (type.is_sfnt () && + !((OpenTypeFontFace&) data.arrayZ).sanitize (c))) return_trace (false); } } commit 6b5e4d07adb6b739dc294da513c4a7acd03977f7 Author: Behdad Esfahbod <[email protected]> Date: Tue Sep 11 17:26:24 2018 +0200 [dfont] Minor diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 39c6aeb8..35a774dd 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -363,10 +363,7 @@ struct ResourceMap return ((&reserved[2])+typeList)[i]; } - inline unsigned int get_types_count () const - { - return nTypes + 1; - } + inline unsigned int get_types_count () const { return nTypes + 1; } inline const ResourceRefItem &get_ref_item (const ResourceTypeItem &type, unsigned int i) const @@ -392,7 +389,7 @@ struct ResourceMap OffsetTo<UnsizedArrayOf<ResourceTypeItem> > typeList; /* Offset from beginning of map to * resource type list */ - HBUINT16 nameList; /* Offset from beginning of map to + Offset16 nameList; /* Offset from beginning of map to * resource name list */ HBUINT16 nTypes; /* Number of types in the map minus 1 */ public: _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
