Bug 1279628, part 1 - Add the CoreGraphics check from gfxASurface::CheckSurfaceSize to Factory::CheckSurfaceSize. r=mstange

This commit is contained in:
Jonathan Watt 2016-06-10 13:32:01 +01:00
parent da8d36cca8
commit 53c34f0b69
2 changed files with 25 additions and 14 deletions

View File

@ -1237,9 +1237,21 @@ public:
static bool HasSSE2();
/** Make sure that the given dimensions don't overflow a 32-bit signed int
* using 4 bytes per pixel; optionally, make sure that either dimension
* doesn't exceed the given limit.
/**
* Returns false if any of the following are true:
*
* - the width/height of |sz| are less than or equal to zero
* - the width/height of |sz| are greater than |limit|
* - the number of bytes that need to be allocated for the surface is too
* big to fit in an int32_t, or bigger than |allocLimit|, if specifed
*
* To calculate the number of bytes that need to be allocated for the surface
* this function makes the conservative assumption that there need to be
* 4 bytes-per-pixel, and the stride alignment is 16 bytes.
*
* The reason for using int32_t rather than uint32_t is again to be
* conservative; some code has in the past and may in the future use signed
* integers to store buffer lengths etc.
*/
static bool CheckSurfaceSize(const IntSize &sz,
int32_t limit = 0,

View File

@ -265,29 +265,28 @@ Factory::CheckSurfaceSize(const IntSize &sz,
return false;
}
// make sure the surface area doesn't overflow a int32_t
CheckedInt<int32_t> tmp = sz.width;
tmp *= sz.height;
if (!tmp.isValid()) {
gfxDebug() << "Surface size too large (would overflow)!";
#if defined(XP_MACOSX)
// CoreGraphics is limited to images < 32K in *height*,
// so clamp all surfaces on the Mac to that height
if (sz.height > SHRT_MAX) {
gfxDebug() << "Surface size too large (exceeds CoreGraphics limit)!";
return false;
}
#endif
// assuming 4 bytes per pixel, make sure the allocation size
// doesn't overflow a int32_t either
CheckedInt<int32_t> stride = sz.width;
stride *= 4;
// When aligning the stride to 16 bytes, it can grow by up to 15 bytes.
stride += 16 - 1;
if (stride.isValid()) {
stride = GetAlignedStride<16>(stride.value());
}
if (!stride.isValid()) {
gfxDebug() << "Surface size too large (stride overflows int32_t)!";
return false;
}
CheckedInt<int32_t> numBytes = GetAlignedStride<16>(sz.width * 4);
numBytes *= sz.height;
CheckedInt<int32_t> numBytes = stride * sz.height;
if (!numBytes.isValid()) {
gfxDebug() << "Surface size too large (allocation size would overflow int32_t)!";
return false;