src/hb-face-private.hh | 2 +- src/hb-object-private.hh | 44 +++++++++++++++++++++++++++++--------------- src/hb-set-private.hh | 2 +- 3 files changed, 31 insertions(+), 17 deletions(-)
New commits: commit a5a27073cfff91c4f80209ca8462543130af61dd Author: Behdad Esfahbod <[email protected]> Date: Thu Aug 14 13:05:36 2014 -0400 Rewrite this==NULL checks to avoid undefined behavior Fixes https://code.google.com/p/chromium/issues/detail?id=403594 diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 8e3c006..1befd6b 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -129,15 +129,11 @@ struct hb_object_header_t template <typename Type> friend Type *hb_object_reference (Type *obj); inline void reference (void) { - if (unlikely (!this || this->is_inert ())) - return; ref_count.inc (); } template <typename Type> friend bool hb_object_destroy (Type *obj); inline bool destroy (void) { - if (unlikely (!this || this->is_inert ())) - return false; if (ref_count.dec () != 1) return false; @@ -156,18 +152,12 @@ struct hb_object_header_t void * data, hb_destroy_func_t destroy_func, hb_bool_t replace) { - if (unlikely (!this || this->is_inert ())) - return false; - return user_data.set (key, data, destroy_func, replace); } template <typename type> friend void *hb_object_get_user_data (type *obj, hb_user_data_key_t *key); inline void *get_user_data (hb_user_data_key_t *key) { - if (unlikely (!this || this->is_inert ())) - return NULL; - return user_data.get (key); } @@ -212,6 +202,8 @@ static inline bool hb_object_is_inert (const Type *obj) template <typename Type> static inline Type *hb_object_reference (Type *obj) { + if (unlikely (!obj || obj->header.is_inert ())) + return obj; hb_object_trace (obj, HB_FUNC); obj->header.reference (); return obj; @@ -219,6 +211,8 @@ static inline Type *hb_object_reference (Type *obj) template <typename Type> static inline bool hb_object_destroy (Type *obj) { + if (unlikely (!obj || obj->header.is_inert ())) + return false; hb_object_trace (obj, HB_FUNC); return obj->header.destroy (); } @@ -229,6 +223,8 @@ static inline bool hb_object_set_user_data (Type *obj, hb_destroy_func_t destroy, hb_bool_t replace) { + if (unlikely (!obj || obj->header.is_inert ())) + return false; return obj->header.set_user_data (key, data, destroy, replace); } @@ -236,6 +232,8 @@ template <typename Type> static inline void *hb_object_get_user_data (Type *obj, hb_user_data_key_t *key) { + if (unlikely (!obj || obj->header.is_inert ())) + return NULL; return obj->header.get_user_data (key); } commit cc3b2d432b02f9381cdf19e2dd5fbbdd002a750c Author: Behdad Esfahbod <[email protected]> Date: Thu Aug 14 12:59:16 2014 -0400 Remove this==NULL check from face->reference_table() Not supposed to happen, and apparently this is undefined in C++. https://code.google.com/p/chromium/issues/detail?id=403594 diff --git a/src/hb-face-private.hh b/src/hb-face-private.hh index 6520d3d..c4266ff 100644 --- a/src/hb-face-private.hh +++ b/src/hb-face-private.hh @@ -66,7 +66,7 @@ struct hb_face_t { { hb_blob_t *blob; - if (unlikely (!this || !reference_table_func)) + if (unlikely (!reference_table_func)) return hb_blob_get_empty (); blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data); commit cd7ea4f791dc41d62ad238673e2ea0107883c9e3 Author: Behdad Esfahbod <[email protected]> Date: Thu Aug 14 12:57:02 2014 -0400 Make hb_object_t members private In preparation for fixing: https://code.google.com/p/chromium/issues/detail?id=403594 diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 8a9ae34..8e3c006 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -68,8 +68,6 @@ struct hb_reference_count_t #define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT} struct hb_user_data_array_t { - /* TODO Add tracing. */ - struct hb_user_data_item_t { hb_user_data_key_t *key; void *data; @@ -106,6 +104,9 @@ struct hb_object_header_t #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT} + private: + + template <typename Type> friend Type *hb_object_create (void); static inline void *create (unsigned int size) { hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size); @@ -115,21 +116,25 @@ struct hb_object_header_t return obj; } + template <typename Type> friend void hb_object_init (Type *obj); inline void init (void) { ref_count.init (1); user_data.init (); } + template <typename Type> friend bool hb_object_is_inert (const Type *obj); inline bool is_inert (void) const { return unlikely (ref_count.is_invalid ()); } + template <typename Type> friend Type *hb_object_reference (Type *obj); inline void reference (void) { if (unlikely (!this || this->is_inert ())) return; ref_count.inc (); } + template <typename Type> friend bool hb_object_destroy (Type *obj); inline bool destroy (void) { if (unlikely (!this || this->is_inert ())) return false; @@ -142,6 +147,11 @@ struct hb_object_header_t return true; } + template <typename Type> friend bool hb_object_set_user_data (Type *obj, + hb_user_data_key_t *key, + void * data, + hb_destroy_func_t destroy, + hb_bool_t replace); inline bool set_user_data (hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy_func, @@ -152,6 +162,8 @@ struct hb_object_header_t return user_data.set (key, data, destroy_func, replace); } + template <typename type> friend void *hb_object_get_user_data (type *obj, + hb_user_data_key_t *key); inline void *get_user_data (hb_user_data_key_t *key) { if (unlikely (!this || this->is_inert ())) return NULL; @@ -159,17 +171,15 @@ struct hb_object_header_t return user_data.get (key); } + template <typename Type> friend void hb_object_trace (const Type *obj, const char *function); inline void trace (const char *function) const { if (unlikely (!this)) return; - /* TODO We cannot use DEBUG_MSG_FUNC here since that one currently only - * prints the class name and throws away the template info. */ DEBUG_MSG (OBJECT, (void *) this, "%s refcount=%d", function, this ? ref_count.ref_count : 0); } - private: ASSERT_POD (); }; @@ -181,6 +191,7 @@ static inline void hb_object_trace (const Type *obj, const char *function) { obj->header.trace (function); } + template <typename Type> static inline Type *hb_object_create (void) { @@ -189,6 +200,11 @@ static inline Type *hb_object_create (void) return obj; } template <typename Type> +static inline void hb_object_init (Type *obj) +{ + obj->header.init (); +} +template <typename Type> static inline bool hb_object_is_inert (const Type *obj) { return unlikely (obj->header.is_inert ()); diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh index 705f554..59e8f45 100644 --- a/src/hb-set-private.hh +++ b/src/hb-set-private.hh @@ -150,7 +150,7 @@ struct hb_set_t bool in_error; inline void init (void) { - header.init (); + hb_object_init (this); clear (); } inline void fini (void) { _______________________________________________ HarfBuzz mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/harfbuzz
