From 73bed4ef57444a2ea066d532a8a82b230fd206d9 Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Fri, 22 Sep 2017 10:53:34 -0400 Subject: Fix crash when rendering invalid GIF The core fix in this CL is a change to how LWZ decompression works, so that when the min code table size and the color palette size are different, color codes after the end of the defined color palette are considered errors. This CL also introduces a bunch of tweaks to the call return path, since there were multiple locations where the GIF decode failing status was being dropped on the floor, so the end widget would have a bitmap with the default colour in it, instead of nothing. BUG=chromium:616671 Change-Id: Id6f40d552dc24650c91e9903f710ff2fa63bc774 Reviewed-on: https://pdfium-review.googlesource.com/14630 Commit-Queue: Ryan Harrison Reviewed-by: dsinclair --- core/fxcodec/codec/ccodec_gifmodule.cpp | 2 +- core/fxcodec/codec/ccodec_progressivedecoder.h | 2 +- core/fxcodec/codec/fx_codec_progress.cpp | 44 ++++++++++++++------------ 3 files changed, 26 insertions(+), 22 deletions(-) (limited to 'core/fxcodec/codec') diff --git a/core/fxcodec/codec/ccodec_gifmodule.cpp b/core/fxcodec/codec/ccodec_gifmodule.cpp index f7e3546a8f..911323c3a1 100644 --- a/core/fxcodec/codec/ccodec_gifmodule.cpp +++ b/core/fxcodec/codec/ccodec_gifmodule.cpp @@ -36,7 +36,7 @@ GifDecodeStatus CCodec_GifModule::ReadHeader(Context* pContext, *width = context->width; *height = context->height; - *pal_num = context->global_pal_num; + *pal_num = (2 << context->global_pal_exp); *pal_pp = context->m_GlobalPalette.empty() ? nullptr : context->m_GlobalPalette.data(); *bg_index = context->bc_index; diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h index 87bed08fcf..05b7c92078 100644 --- a/core/fxcodec/codec/ccodec_progressivedecoder.h +++ b/core/fxcodec/codec/ccodec_progressivedecoder.h @@ -56,7 +56,7 @@ class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate, int32_t GetBPC() const { return m_SrcBPC; } void SetClipBox(FX_RECT* clip); - FXCODEC_STATUS GetFrames(int32_t& frames); + FXCODEC_STATUS GetFrames(int32_t* frames); FXCODEC_STATUS StartDecode(const RetainPtr& pDIBitmap, int start_x, int start_y, diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp index 8b90d3ab84..f10523cc39 100644 --- a/core/fxcodec/codec/fx_codec_progress.cpp +++ b/core/fxcodec/codec/fx_codec_progress.cpp @@ -1791,7 +1791,7 @@ void CCodec_ProgressiveDecoder::Resample( } } -FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames) { +FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t* frames) { if (!(m_status == FXCODEC_STATUS_FRAME_READY || m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) { return FXCODEC_STATUS_ERROR; @@ -1801,7 +1801,8 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames) { case FXCODEC_IMAGE_BMP: case FXCODEC_IMAGE_PNG: case FXCODEC_IMAGE_TIF: - frames = m_FrameNumber = 1; + *frames = 1; + m_FrameNumber = 1; m_status = FXCODEC_STATUS_DECODE_READY; return m_status; case FXCODEC_IMAGE_GIF: { @@ -1822,7 +1823,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames) { pGifModule->LoadFrameInfo(m_pGifContext.get(), &m_FrameNumber); } if (readResult == GifDecodeStatus::Success) { - frames = m_FrameNumber; + *frames = m_FrameNumber; m_status = FXCODEC_STATUS_DECODE_READY; return m_status; } @@ -2108,34 +2109,37 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode() { case FXCODEC_IMAGE_GIF: { CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); if (!pGifModule) { + m_pDeviceBitmap = nullptr; + m_pFile = nullptr; m_status = FXCODEC_STATUS_ERR_MEMORY; return m_status; } - while (true) { - GifDecodeStatus readRes = - pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr); - while (readRes == GifDecodeStatus::Unfinished) { - FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; - if (!GifReadMoreData(pGifModule, error_status)) { - m_pDeviceBitmap = nullptr; - m_pFile = nullptr; - m_status = error_status; - return m_status; - } - readRes = - pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr); - } - if (readRes == GifDecodeStatus::Success) { + + GifDecodeStatus readRes = + pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr); + while (readRes == GifDecodeStatus::Unfinished) { + FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH; + if (!GifReadMoreData(pGifModule, error_status)) { m_pDeviceBitmap = nullptr; m_pFile = nullptr; - m_status = FXCODEC_STATUS_DECODE_FINISH; + m_status = error_status; return m_status; } + readRes = + pGifModule->LoadFrame(m_pGifContext.get(), m_FrameCur, nullptr); + } + + if (readRes == GifDecodeStatus::Success) { m_pDeviceBitmap = nullptr; m_pFile = nullptr; - m_status = FXCODEC_STATUS_ERROR; + m_status = FXCODEC_STATUS_DECODE_FINISH; return m_status; } + + m_pDeviceBitmap = nullptr; + m_pFile = nullptr; + m_status = FXCODEC_STATUS_ERROR; + return m_status; } case FXCODEC_IMAGE_BMP: { CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); -- cgit v1.2.3