From e06880f8eb984a48921f0560bd7ab4e055da432d Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 18 Apr 2018 22:59:32 +0000 Subject: Fix integer overflow in shading drawing code. BUG=chromium:833721 Change-Id: I3ca878760c12144ef27a71dcbbfd7c18d12a5f3b Reviewed-on: https://pdfium-review.googlesource.com/30992 Commit-Queue: Lei Zhang Reviewed-by: Tom Sepez --- core/fpdfapi/render/cpdf_renderstatus.cpp | 42 +++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 8ebced72f7..74e4797b73 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -92,14 +92,21 @@ class CPDF_RefType3Cache { UnownedPtr const m_pType3Font; }; -uint32_t CountOutputs( +uint32_t CountOutputsFromFunctions( const std::vector>& funcs) { - uint32_t total = 0; + FX_SAFE_UINT32 total = 0; for (const auto& func : funcs) { if (func) total += func->CountOutputs(); } - return total; + return total.ValueOrDefault(0); +} + +uint32_t GetValidatedOutputsCount( + const std::vector>& funcs, + const CPDF_ColorSpace* pCS) { + uint32_t funcs_outputs = CountOutputsFromFunctions(funcs); + return funcs_outputs ? std::max(funcs_outputs, pCS->CountComponents()) : 0; } void DrawAxialShading(const RetainPtr& pBitmap, @@ -109,6 +116,11 @@ void DrawAxialShading(const RetainPtr& pBitmap, CPDF_ColorSpace* pCS, int alpha) { ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + + const uint32_t total_results = GetValidatedOutputsCount(funcs, pCS); + if (total_results == 0) + return; + CPDF_Array* pCoords = pDict->GetArrayFor("Coords"); if (!pCoords) return; @@ -136,8 +148,7 @@ void DrawAxialShading(const RetainPtr& pBitmap, float x_span = end_x - start_x; float y_span = end_y - start_y; float axis_len_square = (x_span * x_span) + (y_span * y_span); - uint32_t total_results = - std::max(CountOutputs(funcs), pCS->CountComponents()); + CFX_FixedBufGrow result_array(total_results); float* pResults = result_array; memset(pResults, 0, total_results * sizeof(float)); @@ -194,6 +205,11 @@ void DrawRadialShading(const RetainPtr& pBitmap, CPDF_ColorSpace* pCS, int alpha) { ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + + const uint32_t total_results = GetValidatedOutputsCount(funcs, pCS); + if (total_results == 0) + return; + CPDF_Array* pCoords = pDict->GetArrayFor("Coords"); if (!pCoords) return; @@ -218,8 +234,7 @@ void DrawRadialShading(const RetainPtr& pBitmap, bStartExtend = !!pArray->GetIntegerAt(0); bEndExtend = !!pArray->GetIntegerAt(1); } - uint32_t total_results = - std::max(CountOutputs(funcs), pCS->CountComponents()); + CFX_FixedBufGrow result_array(total_results); float* pResults = result_array; memset(pResults, 0, total_results * sizeof(float)); @@ -326,8 +341,16 @@ void DrawFuncShading(const RetainPtr& pBitmap, CPDF_ColorSpace* pCS, int alpha) { ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + + const uint32_t total_results = GetValidatedOutputsCount(funcs, pCS); + if (total_results == 0) + return; + CPDF_Array* pDomain = pDict->GetArrayFor("Domain"); - float xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f; + float xmin = 0.0f; + float ymin = 0.0f; + float xmax = 1.0f; + float ymax = 1.0f; if (pDomain) { xmin = pDomain->GetNumberAt(0); xmax = pDomain->GetNumberAt(1); @@ -340,8 +363,7 @@ void DrawFuncShading(const RetainPtr& pBitmap, int width = pBitmap->GetWidth(); int height = pBitmap->GetHeight(); int pitch = pBitmap->GetPitch(); - uint32_t total_results = - std::max(CountOutputs(funcs), pCS->CountComponents()); + CFX_FixedBufGrow result_array(total_results); float* pResults = result_array; memset(pResults, 0, total_results * sizeof(float)); -- cgit v1.2.3