diff options
author | Lei Zhang <thestig@chromium.org> | 2018-04-18 22:59:32 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-04-18 22:59:32 +0000 |
commit | e06880f8eb984a48921f0560bd7ab4e055da432d (patch) | |
tree | 89bbce3c48f6e6522cc1f6a1b29f6179e99cd31f | |
parent | a1fe73272892b668bd5928a836ecc6303c81e2fd (diff) | |
download | pdfium-e06880f8eb984a48921f0560bd7ab4e055da432d.tar.xz |
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 <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
-rw-r--r-- | core/fpdfapi/render/cpdf_renderstatus.cpp | 42 |
1 files 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<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 @@ void DrawAxialShading(const RetainPtr<CFX_DIBitmap>& 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<CFX_DIBitmap>& 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<float, 16> result_array(total_results); float* pResults = result_array; memset(pResults, 0, total_results * sizeof(float)); @@ -194,6 +205,11 @@ void DrawRadialShading(const RetainPtr<CFX_DIBitmap>& 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<CFX_DIBitmap>& pBitmap, 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 @@ void DrawFuncShading(const RetainPtr<CFX_DIBitmap>& 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<CFX_DIBitmap>& 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<float, 16> result_array(total_results); float* pResults = result_array; memset(pResults, 0, total_results * sizeof(float)); |