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 --- xfa/fxfa/cxfa_ffimage.cpp | 3 +-- xfa/fxfa/cxfa_ffpageview.cpp | 3 ++- xfa/fxfa/cxfa_ffwidget.cpp | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 35 insertions(+), 9 deletions(-) (limited to 'xfa') diff --git a/xfa/fxfa/cxfa_ffimage.cpp b/xfa/fxfa/cxfa_ffimage.cpp index 757867f076..9903e6b25d 100644 --- a/xfa/fxfa/cxfa_ffimage.cpp +++ b/xfa/fxfa/cxfa_ffimage.cpp @@ -26,8 +26,7 @@ bool CXFA_FFImage::LoadWidget() { if (GetDataAcc()->GetImageImage()) return true; - GetDataAcc()->LoadImageImage(); - return CXFA_FFDraw::LoadWidget(); + return GetDataAcc()->LoadImageImage() ? CXFA_FFDraw::LoadWidget() : false; } void CXFA_FFImage::UnloadWidget() { diff --git a/xfa/fxfa/cxfa_ffpageview.cpp b/xfa/fxfa/cxfa_ffpageview.cpp index 1de900c2f7..0e0db8dae0 100644 --- a/xfa/fxfa/cxfa_ffpageview.cpp +++ b/xfa/fxfa/cxfa_ffpageview.cpp @@ -208,7 +208,8 @@ CXFA_FFWidget* CXFA_FFPageWidgetIterator::GetWidget( if (!pWidget->IsLoaded() && !!(pWidget->GetStatus() & XFA_WidgetStatus_Visible)) { - pWidget->LoadWidget(); + if (!pWidget->LoadWidget()) + return nullptr; } return pWidget; } diff --git a/xfa/fxfa/cxfa_ffwidget.cpp b/xfa/fxfa/cxfa_ffwidget.cpp index 7763a19972..859287388f 100644 --- a/xfa/fxfa/cxfa_ffwidget.cpp +++ b/xfa/fxfa/cxfa_ffwidget.cpp @@ -899,6 +899,17 @@ void XFA_DrawBox(CXFA_Box box, XFA_BOX_Stroke(box, strokes, pGS, rtWidget, matrix, dwFlags); } +bool IsFXCodecErrorStatus(FXCODEC_STATUS status) { + return (status == FXCODEC_STATUS_ERROR || +#ifdef PDF_ENABLE_XFA + status == FXCODEC_STATUS_ERR_MEMORY || +#endif // PDF_ENABLE_XFA + status == FXCODEC_STATUS_ERR_READ || + status == FXCODEC_STATUS_ERR_FLUSH || + status == FXCODEC_STATUS_ERR_FORMAT || + status == FXCODEC_STATUS_ERR_PARAMS); +} + } // namespace CXFA_FFWidget::CXFA_FFWidget(CXFA_WidgetAcc* pDataAcc) @@ -2001,14 +2012,29 @@ RetainPtr XFA_LoadImageFromBuffer( pBitmap->Create(pProgressiveDecoder->GetWidth(), pProgressiveDecoder->GetHeight(), dibFormat); pBitmap->Clear(0xffffffff); + int32_t nFrames; - if ((pProgressiveDecoder->GetFrames(nFrames) == - FXCODEC_STATUS_DECODE_READY) && - (nFrames > 0)) { - pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(), - pBitmap->GetHeight()); - pProgressiveDecoder->ContinueDecode(); + if (pProgressiveDecoder->GetFrames(&nFrames) != FXCODEC_STATUS_DECODE_READY || + nFrames <= 0) { + pBitmap = nullptr; + return pBitmap; + } + + FXCODEC_STATUS status = pProgressiveDecoder->StartDecode( + pBitmap, 0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); + if (IsFXCodecErrorStatus(status)) { + pBitmap = nullptr; + return pBitmap; } + + while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) { + status = pProgressiveDecoder->ContinueDecode(); + if (IsFXCodecErrorStatus(status)) { + pBitmap = nullptr; + return pBitmap; + } + } + return pBitmap; } -- cgit v1.2.3