summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2018-04-18 22:59:32 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-04-18 22:59:32 +0000
commite06880f8eb984a48921f0560bd7ab4e055da432d (patch)
tree89bbce3c48f6e6522cc1f6a1b29f6179e99cd31f
parenta1fe73272892b668bd5928a836ecc6303c81e2fd (diff)
downloadpdfium-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.cpp42
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));