Bug 1213744 (Part 2) - Clamp the GIF frame rect to the visible rect for DDD and don't decode outside it. r=tn

This commit is contained in:
Seth Fowler 2015-10-25 13:14:14 -07:00
Родитель 9c9c634dee
Коммит 6a4428a1e6
2 изменённых файлов: 28 добавлений и 4 удалений

Просмотреть файл

@ -207,7 +207,7 @@ nsGIFDecoder2::BeginGIF()
}
bool
nsGIFDecoder2::CheckForTransparency(IntRect aFrameRect)
nsGIFDecoder2::CheckForTransparency(const IntRect& aFrameRect)
{
// Check if the image has a transparent color in its palette.
if (mGIFStruct.is_transparent) {
@ -231,6 +231,22 @@ nsGIFDecoder2::CheckForTransparency(IntRect aFrameRect)
return false;
}
IntRect
nsGIFDecoder2::ClampToImageRect(const IntRect& aRect)
{
IntRect imageRect(0, 0, mGIFStruct.screen_width, mGIFStruct.screen_height);
IntRect visibleFrameRect = aRect.Intersect(imageRect);
// If there's no intersection, |visibleFrameRect| will be an empty rect
// positioned at the maximum of |imageRect|'s and |aRect|'s coordinates, which
// is not what we want. Force it to (0, 0) in that case.
if (visibleFrameRect.IsEmpty()) {
visibleFrameRect.MoveTo(0, 0);
}
return visibleFrameRect;
}
//******************************************************************************
nsresult
nsGIFDecoder2::BeginImageFrame(uint16_t aDepth)
@ -275,8 +291,8 @@ nsGIFDecoder2::BeginImageFrame(uint16_t aDepth)
}
if (mDownscaler) {
rv = mDownscaler->BeginFrame(GetSize(), Some(frameRect), mImageData,
hasTransparency);
rv = mDownscaler->BeginFrame(GetSize(), Some(ClampToImageRect(frameRect)),
mImageData, hasTransparency);
}
return rv;
@ -487,6 +503,9 @@ nsGIFDecoder2::DoLzw(const uint8_t* q)
if (!mGIFStruct.rows_remaining) {
return true;
}
if (MOZ_UNLIKELY(mDownscaler && mDownscaler->IsFrameComplete())) {
return true;
}
// Copy all the decoder state variables into locals so the compiler
// won't worry about them being aliased. The locals will be homed
@ -543,6 +562,10 @@ nsGIFDecoder2::DoLzw(const uint8_t* q)
return (mGIFStruct.rows_remaining == 0);
}
if (MOZ_UNLIKELY(mDownscaler && mDownscaler->IsFrameComplete())) {
goto END;
}
if (oldcode == -1) {
if (code >= MAX_BITS) {
return false;

Просмотреть файл

@ -50,7 +50,8 @@ private:
bool DoLzw(const uint8_t* q);
bool SetHold(const uint8_t* buf, uint32_t count,
const uint8_t* buf2 = nullptr, uint32_t count2 = 0);
bool CheckForTransparency(gfx::IntRect aFrameRect);
bool CheckForTransparency(const gfx::IntRect& aFrameRect);
gfx::IntRect ClampToImageRect(const gfx::IntRect& aFrameRect);
inline int ClearCode() const { return 1 << mGIFStruct.datasize; }