diff --git a/mfbt/Array.h b/mfbt/Array.h index fd77568ae666..45bf916386e9 100644 --- a/mfbt/Array.h +++ b/mfbt/Array.h @@ -17,6 +17,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" +#include "mozilla/Likely.h" namespace mozilla { @@ -39,12 +40,16 @@ class Array { } T& operator[](size_t aIndex) { - MOZ_ASSERT(aIndex < Length); + if (MOZ_UNLIKELY(aIndex >= Length)) { + detail::InvalidArrayIndex_CRASH(aIndex, Length); + } return mArr[aIndex]; } const T& operator[](size_t aIndex) const { - MOZ_ASSERT(aIndex < Length); + if (MOZ_UNLIKELY(aIndex >= Length)) { + detail::InvalidArrayIndex_CRASH(aIndex, Length); + } return mArr[aIndex]; } diff --git a/mfbt/Assertions.cpp b/mfbt/Assertions.cpp index 1e92191632e9..7721677f1950 100644 --- a/mfbt/Assertions.cpp +++ b/mfbt/Assertions.cpp @@ -44,3 +44,9 @@ MFBT_API MOZ_COLD MOZ_NEVER_INLINE MOZ_FORMAT_PRINTF(1, 2) const } MOZ_END_EXTERN_C + +MFBT_API MOZ_NORETURN MOZ_COLD void mozilla::detail::InvalidArrayIndex_CRASH( + size_t aIndex, size_t aLength) { + MOZ_CRASH_UNSAFE_PRINTF("ElementAt(aIndex = %zu, aLength = %zu)", aIndex, + aLength); +} diff --git a/mfbt/Assertions.h b/mfbt/Assertions.h index 84bed30790c3..5dcb4cb0acd0 100644 --- a/mfbt/Assertions.h +++ b/mfbt/Assertions.h @@ -609,4 +609,15 @@ struct AssertionConditionType { #undef MOZ_DUMP_ASSERTION_STACK #undef MOZ_CRASH_CRASHREPORT +/* + * This is only used by Array and nsTArray classes, therefore it is not + * required when included from C code. + */ +#ifdef __cplusplus +namespace mozilla::detail { +MFBT_API MOZ_NORETURN MOZ_COLD void InvalidArrayIndex_CRASH(size_t aIndex, + size_t aLength); +} // namespace mozilla::detail +#endif // __cplusplus + #endif /* mozilla_Assertions_h */ diff --git a/xpcom/ds/nsTArray-inl.h b/xpcom/ds/nsTArray-inl.h index 9641c5fd06ef..6f5e4bec0af7 100644 --- a/xpcom/ds/nsTArray-inl.h +++ b/xpcom/ds/nsTArray-inl.h @@ -412,7 +412,7 @@ nsTArray_base::InsertSlotsAt(index_type aIndex, size_type aElemSize, size_t aElemAlign) { if (MOZ_UNLIKELY(aIndex > Length())) { - InvalidArrayIndex_CRASH(aIndex, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aIndex, Length()); } if (!ActualAlloc::Successful( diff --git a/xpcom/ds/nsTArray.cpp b/xpcom/ds/nsTArray.cpp index d252fd127405..50326fb331b4 100644 --- a/xpcom/ds/nsTArray.cpp +++ b/xpcom/ds/nsTArray.cpp @@ -23,13 +23,6 @@ bool IsTwiceTheRequiredBytesRepresentableAsUint32(size_t aCapacity, return ((CheckedUint32(aCapacity) * aElemSize) * 2).isValid(); } -MOZ_NORETURN MOZ_COLD void InvalidArrayIndex_CRASH(size_t aIndex, - size_t aLength) { - MOZ_CRASH_UNSAFE_PRINTF( - "ElementAt(aIndex = %" PRIu64 ", aLength = %" PRIu64 ")", - static_cast(aIndex), static_cast(aLength)); -} - void ::detail::SetCycleCollectionArrayFlag(uint32_t& aFlags) { aFlags |= CycleCollectionEdgeNameArrayFlag; } diff --git a/xpcom/ds/nsTArray.h b/xpcom/ds/nsTArray.h index 92fe4a46490e..f85571f142ce 100644 --- a/xpcom/ds/nsTArray.h +++ b/xpcom/ds/nsTArray.h @@ -376,9 +376,6 @@ extern "C" void Gecko_EnsureTArrayCapacity(void* aArray, size_t aCapacity, extern "C" void Gecko_ClearPODTArray(void* aArray, size_t aElementSize, size_t aElementAlign); -MOZ_NORETURN MOZ_COLD void InvalidArrayIndex_CRASH(size_t aIndex, - size_t aLength); - // // This class serves as a base class for nsTArray. It shouldn't be used // directly. It holds common implementation code that does not depend on the @@ -1197,7 +1194,7 @@ class nsTArray_Impl // @return A reference to the i'th element of the array. [[nodiscard]] elem_type& ElementAt(index_type aIndex) { if (MOZ_UNLIKELY(aIndex >= Length())) { - InvalidArrayIndex_CRASH(aIndex, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aIndex, Length()); } return Elements()[aIndex]; } @@ -1208,7 +1205,7 @@ class nsTArray_Impl // @return A const reference to the i'th element of the array. [[nodiscard]] const elem_type& ElementAt(index_type aIndex) const { if (MOZ_UNLIKELY(aIndex >= Length())) { - InvalidArrayIndex_CRASH(aIndex, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aIndex, Length()); } return Elements()[aIndex]; } @@ -1871,7 +1868,7 @@ class nsTArray_Impl MOZ_ASSERT(!base_type::IsEmpty()); const size_type oldLen = Length(); if (MOZ_UNLIKELY(0 == oldLen)) { - InvalidArrayIndex_CRASH(1, 0); + mozilla::detail::InvalidArrayIndex_CRASH(1, 0); } elem_type elem = std::move(Elements()[oldLen - 1]); TruncateLengthUnsafe(oldLen - 1); @@ -2248,7 +2245,7 @@ class nsTArray_Impl MOZ_ASSERT(aNewLen <= Length(), "caller should use SetLength instead"); if (MOZ_UNLIKELY(aNewLen > Length())) { - InvalidArrayIndex_CRASH(aNewLen, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aNewLen, Length()); } TruncateLengthUnsafe(aNewLen); @@ -2459,7 +2456,7 @@ auto nsTArray_Impl::ReplaceElementsAtInternal(index_type aStart, size_type aArrayLen) -> elem_type* { if (MOZ_UNLIKELY(aStart > Length())) { - InvalidArrayIndex_CRASH(aStart, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aStart, Length()); } // Adjust memory allocation up-front to catch errors. @@ -2483,7 +2480,7 @@ void nsTArray_Impl::RemoveElementsAt(index_type aStart, rangeEnd += aCount; if (MOZ_UNLIKELY(!rangeEnd.isValid() || rangeEnd.value() > Length())) { - InvalidArrayIndex_CRASH(aStart, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aStart, Length()); } RemoveElementsAtUnsafe(aStart, aCount); @@ -2506,7 +2503,7 @@ void nsTArray_Impl::UnorderedRemoveElementsAt(index_type aStart, rangeEnd += aCount; if (MOZ_UNLIKELY(!rangeEnd.isValid() || rangeEnd.value() > Length())) { - InvalidArrayIndex_CRASH(aStart, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aStart, Length()); } // Destroy the elements which are being removed, and then swap elements in to @@ -2576,7 +2573,7 @@ template auto nsTArray_Impl::InsertElementAtInternal(index_type aIndex) -> elem_type* { if (MOZ_UNLIKELY(aIndex > Length())) { - InvalidArrayIndex_CRASH(aIndex, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aIndex, Length()); } // Length() + 1 is guaranteed to not overflow, so EnsureCapacity is OK. @@ -2597,7 +2594,7 @@ auto nsTArray_Impl::InsertElementAtInternal(index_type aIndex, Item&& aItem) -> elem_type* { if (MOZ_UNLIKELY(aIndex > Length())) { - InvalidArrayIndex_CRASH(aIndex, Length()); + mozilla::detail::InvalidArrayIndex_CRASH(aIndex, Length()); } // Length() + 1 is guaranteed to not overflow, so EnsureCapacity is OK.