diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index a14d0f021..bae73da4d 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -339,16 +339,27 @@ struct UnsizedArrayOf HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); - /* Unlikely other places, use "int i" instead of "unsigned int i" for our - * indexing operator. For two reasons: + /* Unlikely other places, use "ssize_t i" instead of "unsigned int i" for our + * indexing operator. For three reasons: * 1. For UnsizedArrayOf, it's not totally unimaginable to want to look * at items before the start of current array. - * 2. Fixes MSVC 2008 "overloads have similar conversions" issue with the + * 2. Use the largest type, to help detect overflows. + * 3. Fixes MSVC 2008 "overloads have similar conversions" issue with the * built-in operator [] that takes int, in expressions like sizeof (array[0])). * I suppose I could fix that by replacing 0 with 0u, but like this fix * more now. */ - inline const Type& operator [] (int i) const { return arrayZ[i]; } - inline Type& operator [] (int i) { return arrayZ[i]; } + inline const Type& operator [] (ssize_t i) const + { + const Type *p = &arrayZ[i]; + if (unlikely ((0 <= i) != (arrayZ <= p))) return Null (Type); /* Over/under-flowed. */ + return *p; + } + inline Type& operator [] (ssize_t i) + { + const Type *p = &arrayZ[i]; + if (unlikely ((0 <= i) != (arrayZ <= p))) return Crap (Type); /* Over/under-flowed. */ + return *p; + } template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; }