summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2015-01-29 18:02:20 -0800
committerTom Sepez <tsepez@chromium.org>2015-01-29 18:02:20 -0800
commit14b2bb0adcd723a463140929cbd9453a799a34e6 (patch)
treea50085210476a07059eb2467a69b3f2f7cdcdfa5
parent1d43e82efde0ddbad4a3e32d860a597c3bb6ab83 (diff)
downloadpdfium-14b2bb0adcd723a463140929cbd9453a799a34e6.tar.xz
Fix infinite recursion in CPDF_RenderStatus::RenderSingleObject().
Introduce a local static to track the recursion depth, thereby removing the burden for callers to track and pass a level parameter correctly through all call paths. Also increase the depth tolerated, since we know there were paths that were under-counting this value. BUG=451265 R=thestig@chromium.org Review URL: https://codereview.chromium.org/868253009
-rw-r--r--core/src/fpdfapi/fpdf_render/fpdf_render.cpp31
-rw-r--r--core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp10
-rw-r--r--core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp2
-rw-r--r--core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp4
-rw-r--r--core/src/fpdfapi/fpdf_render/render_int.h7
5 files changed, 30 insertions, 24 deletions
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<int> 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;