diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 63af4a6a2..50a929bec 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -48,6 +48,7 @@ #ifndef HB_NO_VISIBILITY const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; #endif void cbdt_callback (const uint8_t* data, unsigned int length, diff --git a/src/dump-fon.cc b/src/dump-fon.cc index 81525f429..827de4a3e 100644 --- a/src/dump-fon.cc +++ b/src/dump-fon.cc @@ -28,6 +28,7 @@ #ifndef HB_NO_VISIBILITY const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; #endif template struct LEInt; diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 1c771b098..6f639dca5 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -932,6 +932,7 @@ struct ArrayOf } inline Type& operator [] (unsigned int i) { + if (unlikely (i >= len)) return Crap(Type); return arrayZ[i]; } inline unsigned int get_size (void) const @@ -1040,6 +1041,11 @@ struct OffsetListOf : OffsetArrayOf if (unlikely (i >= this->len)) return Null(Type); return this+this->arrayZ[i]; } + inline const Type& operator [] (unsigned int i) + { + if (unlikely (i >= this->len)) return Crap(Type); + return this+this->arrayZ[i]; + } inline bool sanitize (hb_sanitize_context_t *c) const { @@ -1064,6 +1070,11 @@ struct HeadlessArrayOf if (unlikely (i >= len || !i)) return Null(Type); return arrayZ[i-1]; } + inline Type& operator [] (unsigned int i) + { + if (unlikely (i >= len || !i)) return Crap(Type); + return arrayZ[i-1]; + } inline unsigned int get_size (void) const { return len.static_size + (len ? len - 1 : 0) * Type::static_size; } diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 368a84658..670495453 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -48,6 +48,7 @@ #ifndef HB_NO_VISIBILITY const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; #endif diff --git a/src/hb-private.hh b/src/hb-private.hh index 4b9668e03..4318eb972 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -529,7 +529,7 @@ _hb_ceil_to_4 (unsigned int v) */ /* - * Null objects + * Static pools */ /* Global nul-content Null pool. Enlarge as necessary. */ @@ -547,7 +547,6 @@ const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {} #endif ; - /* Generic nul-content Null objects. */ template static inline const Type& Null (void) { @@ -569,6 +568,28 @@ namespace Namespace { \ static_assert (Namespace::Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small. Enlarge.") +/* Global writable pool. Enlarge as necessary. */ + +#ifdef HB_NO_VISIBILITY +static +#else +extern HB_INTERNAL +#endif +void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] +#ifdef HB_NO_VISIBILITY += {} +#endif +; +/* CRAP pool: Common Region for Access Protection. */ +template +static inline Type& Crap (void) { + static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + Type *obj = reinterpret_cast (_hb_CrapPool); + *obj = Null(Type); + return *obj; +} +#define Crap(Type) Crap() + /* arrays and maps */ @@ -589,8 +610,18 @@ struct hb_vector_t arrayZ = static_array; } - inline Type& operator [] (unsigned int i) { return arrayZ[i]; } - inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } + inline Type& operator [] (unsigned int i) + { + if (unlikely (i >= len)) + return Crap (Type); + return arrayZ[i]; + } + inline const Type& operator [] (unsigned int i) const + { + if (unlikely (i >= len)) + return Null (Type); + return arrayZ[i]; + } inline Type *push (void) { diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 98f95e021..ad273d047 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -46,6 +46,7 @@ #if !defined(HB_NO_VISIBILITY) && !defined(HB_SUBSET_BUILTIN) const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; #endif diff --git a/src/main.cc b/src/main.cc index 9a1873665..f32490e76 100644 --- a/src/main.cc +++ b/src/main.cc @@ -39,6 +39,7 @@ using namespace OT; #ifndef HB_NO_VISIBILITY const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; #endif int