Fix heap buffer overflow in CPDF_SampledFunc::v_Call

This issue was caused by integer overflow in CPDF_SampledFunc::v_Call.
The root cause of this issue is that the content in the test pdf file
was damaged. The solution is to check whether an integer is overflow
before using it.

BUG=452455
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/886953002
diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp
index 649bd54..3ceb0f7 100644
--- a/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp
+++ b/core/src/fpdfapi/fpdf_page/fpdf_page_func.cpp
@@ -6,6 +6,7 @@
 
 #include "../../../include/fpdfapi/fpdf_page.h"
 #include "../../../include/fpdfapi/fpdf_module.h"
+#include "../../../third_party/numerics/safe_conversions_impl.h"
 #include "pageint.h"
 #include <limits.h>
 class CPDF_PSEngine;
@@ -553,13 +554,24 @@
         }
         pos += index[i] * blocksize[i];
     }
-    int bitpos = pos * m_nBitsPerSample * m_nOutputs;
+    FX_SAFE_INT32 bitpos = pos;
+    bitpos *= m_nBitsPerSample;
+    bitpos *= m_nOutputs;
+    if (!bitpos.IsValid()) {
+        return FALSE;
+    }
     FX_LPCBYTE pSampleData = m_pSampleStream->GetData();
     if (pSampleData == NULL) {
         return FALSE;
     }
+    FX_SAFE_INT32 bitpos1 = m_nOutputs - 1 > 0 ? m_nOutputs - 1 : 0; 
+    bitpos1 *= m_nBitsPerSample;
+    bitpos1 += bitpos.ValueOrDie();
+    if (!bitpos1.IsValid()) {
+        return FALSE;
+    }
     for (int j = 0; j < m_nOutputs; j ++) {
-        FX_DWORD sample = _GetBits32(pSampleData, bitpos + j * m_nBitsPerSample, m_nBitsPerSample);
+        FX_DWORD sample = _GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, m_nBitsPerSample);
         FX_FLOAT encoded = (FX_FLOAT)sample;
         for (int i = 0; i < m_nInputs; i ++) {
             if (index[i] == m_pEncodeInfo[i].sizes - 1) {
@@ -567,8 +579,15 @@
                     encoded = encoded_input[i] * (FX_FLOAT)sample;
                 }
             } else {
-                int bitpos1 = bitpos + m_nBitsPerSample * m_nOutputs * blocksize[i];
-                FX_DWORD sample1 = _GetBits32(pSampleData, bitpos1 + j * m_nBitsPerSample, m_nBitsPerSample);
+                FX_SAFE_INT32 bitpos2 = blocksize[i];
+                bitpos2 += 1;
+                bitpos2 *= m_nBitsPerSample; 
+                bitpos2 *= m_nOutputs;
+                bitpos2 += bitpos.ValueOrDie();
+                if (!bitpos2.IsValid()) {
+                    return FALSE;
+                }
+                FX_DWORD sample1 = _GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample);
                 encoded += (encoded_input[i] - index[i]) * ((FX_FLOAT)sample1 - (FX_FLOAT)sample);
             }
         }