Detect over/under-flow in UnsizedArray::operator[]
Was causing bad substitutions in mort table because of WordOffsetToIndex() producing negative numbers that were cast to unsigned int and returned as large numbers (which was desirable, so they would be rejected), but then they were cast to int when passed to this operator and acting as small negative integers, which was bad... Detect overflow. Ouch, however, now I see this still fails on 32-bit. Guess I'm going to revert an earlier change.
This commit is contained in:
parent
6910ff03e6
commit
52f61cdb87
|
@ -339,16 +339,27 @@ struct UnsizedArrayOf
|
||||||
|
|
||||||
HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type);
|
HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type);
|
||||||
|
|
||||||
/* Unlikely other places, use "int i" instead of "unsigned int i" for our
|
/* Unlikely other places, use "ssize_t i" instead of "unsigned int i" for our
|
||||||
* indexing operator. For two reasons:
|
* indexing operator. For three reasons:
|
||||||
* 1. For UnsizedArrayOf, it's not totally unimaginable to want to look
|
* 1. For UnsizedArrayOf, it's not totally unimaginable to want to look
|
||||||
* at items before the start of current array.
|
* 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])).
|
* 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
|
* I suppose I could fix that by replacing 0 with 0u, but like this fix
|
||||||
* more now. */
|
* more now. */
|
||||||
inline const Type& operator [] (int i) const { return arrayZ[i]; }
|
inline const Type& operator [] (ssize_t i) const
|
||||||
inline Type& operator [] (int i) { return arrayZ[i]; }
|
{
|
||||||
|
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 <typename T> inline operator T * (void) { return arrayZ; }
|
template <typename T> inline operator T * (void) { return arrayZ; }
|
||||||
template <typename T> inline operator const T * (void) const { return arrayZ; }
|
template <typename T> inline operator const T * (void) const { return arrayZ; }
|
||||||
|
|
Loading…
Reference in New Issue