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));