From 09dc51a44ba2c084ca553d8a52ba6e2e669f4f9c Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Thu, 29 Jan 2015 18:16:16 -0800 Subject: Merge to XFA: Fix infinite recursion in CPDF_RenderStatus::RenderSingleObject(). This brings in: 14b2bb0 Fix infinite recursion in CPDF_RenderStatus::RenderSingleObject(). 1d43e82 Add minimized test cases for stack exhaustion crash to repository. TBR=thestig@chromium.org Review URL: https://codereview.chromium.org/893493002 --- core/src/fpdfapi/fpdf_render/fpdf_render.cpp | 31 +++---- core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp | 10 +-- .../fpdfapi/fpdf_render/fpdf_render_pattern.cpp | 2 +- core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp | 4 +- core/src/fpdfapi/fpdf_render/render_int.h | 7 +- testing/resources/bug_451265.in | 80 ++++++++++++++++++ testing/resources/bug_451265.pdf | 98 ++++++++++++++++++++++ 7 files changed, 208 insertions(+), 24 deletions(-) create mode 100644 testing/resources/bug_451265.in create mode 100644 testing/resources/bug_451265.pdf diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render.cpp index ab1ddb6e85..490ceb9ee2 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render.cpp @@ -180,11 +180,14 @@ FX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const b = (bb - fb) * gray / 255 + fb; return ArgbEncode(a, r, g, b); } + +// static +int CPDF_RenderStatus::s_CurrentRecursionDepth = 0; + CPDF_RenderStatus::CPDF_RenderStatus() { m_pContext = NULL; m_bStopped = FALSE; - m_Level = 0; m_pDevice = NULL; m_pCurObj = NULL; m_pStopObj = NULL; @@ -203,13 +206,15 @@ CPDF_RenderStatus::CPDF_RenderStatus() m_pPageResource = NULL; m_curBlend = FXDIB_BLEND_NORMAL; } + CPDF_RenderStatus::~CPDF_RenderStatus() { if (m_pObjectRenderer) { delete m_pObjectRenderer; } } -FX_BOOL CPDF_RenderStatus::Initialize(int level, CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, + +FX_BOOL CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, const CFX_AffineMatrix* pDeviceMatrix, const CPDF_PageObject* pStopObj, const CPDF_RenderStatus* pParentState, const CPDF_GraphicStates* pInitialStates, const CPDF_RenderOptions* pOptions, int transparency, FX_BOOL bDropObjects, @@ -217,7 +222,6 @@ FX_BOOL CPDF_RenderStatus::Initialize(int level, CPDF_RenderContext* pContext, C FX_ARGB fill_color, FX_DWORD GroupFamily, FX_BOOL bLoadMask) { - m_Level = level; m_pContext = pContext; m_pDevice = pDevice; m_DitherBits = pDevice->GetDeviceCaps(FXDC_DITHER_BITS); @@ -262,9 +266,6 @@ FX_BOOL CPDF_RenderStatus::Initialize(int level, CPDF_RenderContext* pContext, C } void CPDF_RenderStatus::RenderObjectList(const CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObj2Device) { - if (m_Level > 32) { - return; - } CFX_FloatRect clip_rect = m_pDevice->GetClipBox(); CFX_AffineMatrix device2object; device2object.SetReverse(*pObj2Device); @@ -293,14 +294,16 @@ void CPDF_RenderStatus::RenderObjectList(const CPDF_PageObjects* pObjs, const CF } void CPDF_RenderStatus::RenderSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device) { - if (m_Level > 32) { + CFX_AutoRestorer restorer(&s_CurrentRecursionDepth); + if (++s_CurrentRecursionDepth > kRenderMaxRecursionDepth) { return; } m_pCurObj = pObj; - if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) + if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) { if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) { return; } + } ProcessClipPath(pObj->m_ClipPath, pObj2Device); if (ProcessTransparency(pObj, pObj2Device)) { return; @@ -462,7 +465,7 @@ void CPDF_RenderStatus::DrawObjWithBackground(const CPDF_PageObject* pObj, const } } CPDF_RenderStatus status; - status.Initialize(m_Level + 1, m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, pFormResource); + status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, pFormResource); status.RenderSingleObject(pObj, &matrix); buffer.OutputToDevice(); } @@ -479,7 +482,7 @@ FX_BOOL CPDF_RenderStatus::ProcessForm(CPDF_FormObject* pFormObj, const CFX_Affi pResources = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); } CPDF_RenderStatus status; - status.Initialize(m_Level + 1, m_pContext, m_pDevice, NULL, m_pStopObj, + status.Initialize(m_pContext, m_pDevice, NULL, m_pStopObj, this, pFormObj, &m_Options, m_Transparency, m_bDropObjects, pResources, FALSE); status.m_curBlend = m_curBlend; m_pDevice->SaveState(); @@ -837,7 +840,7 @@ FX_BOOL CPDF_RenderStatus::ProcessTransparency(const CPDF_PageObject* pPageObj, } } CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL, + bitmap_render.Initialize(m_pContext, &bitmap_device, NULL, m_pStopObj, NULL, NULL, &m_Options, 0, m_bDropObjects, pFormResource, TRUE); bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix); m_bStopped = bitmap_render.m_bStopped; @@ -1001,7 +1004,7 @@ void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_PageObject CFX_AffineMatrix FinalMatrix = pItem->m_Matrix; FinalMatrix.Concat(*pLastMatrix); CPDF_RenderStatus status; - status.Initialize(0, this, pDevice, pLastMatrix, pStopObj, NULL, NULL, pOptions, + status.Initialize(this, pDevice, pLastMatrix, pStopObj, NULL, NULL, pOptions, pItem->m_pObjectList->m_Transparency, FALSE, NULL); status.RenderObjectList(pItem->m_pObjectList, &FinalMatrix); if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { @@ -1013,7 +1016,7 @@ void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_PageObject } } else { CPDF_RenderStatus status; - status.Initialize(0, this, pDevice, NULL, pStopObj, NULL, NULL, pOptions, + status.Initialize(this, pDevice, NULL, pStopObj, NULL, NULL, pOptions, pItem->m_pObjectList->m_Transparency, FALSE, NULL); status.RenderObjectList(pItem->m_pObjectList, &pItem->m_Matrix); if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { @@ -1117,7 +1120,7 @@ void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause) m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition(); m_ObjectIndex = 0; m_pRenderer = FX_NEW CPDF_RenderStatus(); - m_pRenderer->Initialize(0, m_pContext, m_pDevice, NULL, NULL, NULL, NULL, + m_pRenderer->Initialize(m_pContext, m_pDevice, NULL, NULL, NULL, NULL, m_pOptions, pItem->m_pObjectList->m_Transparency, m_bDropObjects, NULL); m_pDevice->SaveState(); m_ClipRect = m_pDevice->GetClipBox(); diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp index ffe559ad54..02da1d93fe 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp @@ -489,7 +489,7 @@ FX_BOOL CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) bitmap_device1.GetBitmap()->Clear(0xffffff); { CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL, + bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL, NULL, NULL, &m_pRenderStatus->m_Options, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); CFX_Matrix patternDevice = *pObj2Device; patternDevice.Translate((FX_FLOAT) - rect.left, (FX_FLOAT) - rect.top); @@ -506,7 +506,7 @@ FX_BOOL CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) } bitmap_device2.GetBitmap()->Clear(0); CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL, + bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL, NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); CPDF_ImageRenderer image_render; if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) { @@ -579,7 +579,7 @@ FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() bitmap_device1.GetBitmap()->Clear(0xffffff); { CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL, + bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL, NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); CPDF_ImageRenderer image_render; if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix, m_Flags, TRUE)) { @@ -593,7 +593,7 @@ FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() } bitmap_device2.GetBitmap()->Clear(0); CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->m_Level + 1, m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL, + bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL, NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); CPDF_ImageRenderer image_render; if (image_render.Start(&bitmap_render, m_Loader.m_pMask, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) { @@ -1034,7 +1034,7 @@ CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict, CPDF_RenderOptions options; options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA; CPDF_RenderStatus status; - status.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL, NULL, NULL, NULL, + status.Initialize(m_pContext, &bitmap_device, NULL, NULL, NULL, NULL, &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity); status.RenderObjectList(&form, &matrix); pMask = FX_NEW CFX_DIBitmap; diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp index 6b895b525b..8024c991f4 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp @@ -988,7 +988,7 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, CPDF_Pag matrix.Translate(orig_x - mtPattern2Device.e, orig_y - mtPattern2Device.f); m_pDevice->SaveState(); CPDF_RenderStatus status; - status.Initialize(m_Level + 1, m_pContext, m_pDevice, NULL, NULL, this, pStates, &m_Options, + status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, &m_Options, pPattern->m_pForm->m_Transparency, m_bDropObjects, pFormResource); status.RenderObjectList(pPattern->m_pForm, &matrix); m_pDevice->RestoreState(); diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp index 449b003c56..f99f7cec38 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp @@ -423,7 +423,7 @@ FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, cons } if (fill_alpha == 255) { CPDF_RenderStatus status; - status.Initialize(m_Level + 1, m_pContext, m_pDevice, NULL, NULL, this, pStates, &Options, + status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, &Options, pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb); status.m_Type3FontCache.Append(m_Type3FontCache); status.m_Type3FontCache.Add(pType3Font); @@ -440,7 +440,7 @@ FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, cons } bitmap_device.GetBitmap()->Clear(0); CPDF_RenderStatus status; - status.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL, NULL, this, pStates, &Options, + status.Initialize(m_pContext, &bitmap_device, NULL, NULL, this, pStates, &Options, pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb); status.m_Type3FontCache.Append(m_Type3FontCache); status.m_Type3FontCache.Add(pType3Font); diff --git a/core/src/fpdfapi/fpdf_render/render_int.h b/core/src/fpdfapi/fpdf_render/render_int.h index 81feb5eb88..bd7d375837 100644 --- a/core/src/fpdfapi/fpdf_render/render_int.h +++ b/core/src/fpdfapi/fpdf_render/render_int.h @@ -92,7 +92,7 @@ class CPDF_RenderStatus : public CFX_Object public: CPDF_RenderStatus(); ~CPDF_RenderStatus(); - FX_BOOL Initialize(int level, class CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, const CFX_AffineMatrix* pDeviceMatrix, + FX_BOOL Initialize(class CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, const CFX_AffineMatrix* pDeviceMatrix, const CPDF_PageObject* pStopObj, const CPDF_RenderStatus* pParentStatus, const CPDF_GraphicStates* pInitialStates, const CPDF_RenderOptions* pOptions, int transparency, FX_BOOL bDropObjects, CPDF_Dictionary* pFormResource = NULL, @@ -155,8 +155,11 @@ protected: void DitherObjectArea(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device); FX_BOOL GetObjectClippedRect(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bLogical, FX_RECT &rect) const; void GetScaledMatrix(CFX_Matrix &matrix) const; + protected: - int m_Level; + static const int kRenderMaxRecursionDepth = 64; + static int s_CurrentRecursionDepth; + CFX_RenderDevice* m_pDevice; CFX_AffineMatrix m_DeviceMatrix; CPDF_ClipPath m_LastClipPath; diff --git a/testing/resources/bug_451265.in b/testing/resources/bug_451265.in new file mode 100644 index 0000000000..7fb2764d05 --- /dev/null +++ b/testing/resources/bug_451265.in @@ -0,0 +1,80 @@ +{{header}} +{{object 1 0}} << + /Kids [3 0 R] + /Type /Pages + /Count 1 +>> +endobj +{{object 2 0}} << + /Type /Catalog + /Pages 1 0 R +>> +endobj +{{object 3 0}} << + /Resources 11 0 R + /Type /Page + /Contents 10 0 R + /Parent 1 0 R +>> +endobj +{{object 10 0}} << +>> +stream +1 0 0 1 315.779 733.039 cm +1 0 0 1 2.835 -173.614 cm +1.04704 0 0 1.04704 0 0 cm +/Im6 Do +endstream +endobj +{{object 11 0}} << + /XObject << + /Im6 12 0 R + >> +>> +endobj +{{object 12 0}} << + /Subtype /Form + /Resources << + /XObject << + /x15 13 0 R + >> + >> +>> +stream +/x15 Do +endstream +endobj +{{object 13 0}} << + /Subtype /Form + /Resources << + /Pattern << + /p31 14 0 R + >> + >> +>> +stream +q /Pattern cs /p31 scn /a0 gs +0 0 224.720001 160.399994 re f +Q +endstream +endobj +{{object 14 0}} << + /PatternType 1 + /BBox [0 0 225 161] + /Resources << + /XObject << + /x47 12 0 R + >> + >> +>> +stream +/x47 Do +endstream +endobj +{{xref}} +trailer << + /Root 2 0 R + /Size 110 +>> +{{startxref}} +%%EOF diff --git a/testing/resources/bug_451265.pdf b/testing/resources/bug_451265.pdf new file mode 100644 index 0000000000..299363dac7 --- /dev/null +++ b/testing/resources/bug_451265.pdf @@ -0,0 +1,98 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Kids [3 0 R] + /Type /Pages + /Count 1 +>> +endobj +2 0 obj << + /Type /Catalog + /Pages 1 0 R +>> +endobj +3 0 obj << + /Resources 11 0 R + /Type /Page + /Contents 10 0 R + /Parent 1 0 R +>> +endobj +10 0 obj << +>> +stream +1 0 0 1 315.779 733.039 cm +1 0 0 1 2.835 -173.614 cm +1.04704 0 0 1.04704 0 0 cm +/Im6 Do +endstream +endobj +11 0 obj << + /XObject << + /Im6 12 0 R + >> +>> +endobj +12 0 obj << + /Subtype /Form + /Resources << + /XObject << + /x15 13 0 R + >> + >> +>> +stream +/x15 Do +endstream +endobj +13 0 obj << + /Subtype /Form + /Resources << + /Pattern << + /p31 14 0 R + >> + >> +>> +stream +q /Pattern cs /p31 scn /a0 gs +0 0 224.720001 160.399994 re f +Q +endstream +endobj +14 0 obj << + /PatternType 1 + /BBox [0 0 225 161] + /Resources << + /XObject << + /x47 12 0 R + >> + >> +>> +stream +/x47 Do +endstream +endobj +xref +0 15 +0000000000 65536 f +0000000015 00000 n +0000000078 00000 n +0000000131 00000 n +0000000000 65536 f +0000000000 65536 f +0000000000 65536 f +0000000000 65536 f +0000000000 65536 f +0000000000 65536 f +0000000221 00000 n +0000000348 00000 n +0000000405 00000 n +0000000531 00000 n +0000000712 00000 n +trailer << + /Root 2 0 R + /Size 110 +>> +startxref +860 +%%EOF -- cgit v1.2.3