// Returns true if an image of aWidth x aHeight is allowed and legal. static bool AllowedImageSize(int32_t aWidth, int32_t aHeight) { // reject over-wide or over-tall images const int32_t k64KLimit = 0x0000FFFF; if (MOZ_UNLIKELY(aWidth > k64KLimit || aHeight > k64KLimit )) { NS_WARNING("image too big"); return false; } // protect against invalid sizes if (MOZ_UNLIKELY(aHeight <= 0 || aWidth <= 0)) { return false; } // check to make sure we don't overflow a 32-bit CheckedInt32 requiredBytes = CheckedInt32(aWidth) * CheckedInt32(aHeight) * 4; if (MOZ_UNLIKELY(!requiredBytes.isValid())) { NS_WARNING("width or height too large"); return false; } #if defined(XP_MACOSX) // CoreGraphics is limited to images < 32K in *height*, so clamp all surfaces // on the Mac to that height if (MOZ_UNLIKELY(aHeight > SHRT_MAX)) { NS_WARNING("image too big"); return false; } #endif return true; }
size_t BufferSizeFromStrideAndHeight(int32_t aStride, int32_t aHeight, int32_t aExtraBytes) { if (MOZ_UNLIKELY(aHeight <= 0)) { return 0; } // We limit the length returned to values that can be represented by int32_t // because we don't want to allocate buffers any bigger than that. This // allows for a buffer size of over 2 GiB which is already rediculously // large and will make the process janky. (Note the choice of the signed type // is deliberate because we specifically don't want the returned value to // overflow if someone stores the buffer length in an int32_t variable.) CheckedInt32 requiredBytes = CheckedInt32(aStride) * CheckedInt32(aHeight) + CheckedInt32(aExtraBytes); if (MOZ_UNLIKELY(!requiredBytes.isValid())) { gfxWarning() << "Buffer size too big; returning zero"; return 0; } return requiredBytes.value(); }