M66: Fix integer overflow in shading drawing code. BUG=chromium:833721 TBR=tsepez@chromium.org Change-Id: I3ca878760c12144ef27a71dcbbfd7c18d12a5f3b Reviewed-on: https://pdfium-review.googlesource.com/30992 Commit-Queue: Lei Zhang <thestig@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org> (cherry picked from commit e06880f8eb984a48921f0560bd7ab4e055da432d) Reviewed-on: https://pdfium-review.googlesource.com/32195 Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 0a01ae0..ece6fc7 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -92,14 +92,21 @@ UnownedPtr<CPDF_Type3Font> const m_pType3Font; }; -uint32_t CountOutputs( +uint32_t CountOutputsFromFunctions( const std::vector<std::unique_ptr<CPDF_Function>>& 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<std::unique_ptr<CPDF_Function>>& 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<CFX_DIBitmap>& pBitmap, @@ -109,6 +116,11 @@ 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 @@ 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<float, 16> result_array(total_results); float* pResults = result_array; memset(pResults, 0, total_results * sizeof(float)); @@ -194,6 +205,11 @@ 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 @@ bStartExtend = !!pArray->GetIntegerAt(0); bEndExtend = !!pArray->GetIntegerAt(1); } - uint32_t total_results = - std::max(CountOutputs(funcs), pCS->CountComponents()); + CFX_FixedBufGrow<float, 16> result_array(total_results); float* pResults = result_array; memset(pResults, 0, total_results * sizeof(float)); @@ -326,8 +341,16 @@ 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 @@ int width = pBitmap->GetWidth(); int height = pBitmap->GetHeight(); int pitch = pBitmap->GetPitch(); - uint32_t total_results = - std::max(CountOutputs(funcs), pCS->CountComponents()); + CFX_FixedBufGrow<float, 16> result_array(total_results); float* pResults = result_array; memset(pResults, 0, total_results * sizeof(float));