summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLE GARREC Vincent <gitlab-freedesktop@le-garrec.fr>2019-03-31 00:33:09 +0000
committerAlbert Astals Cid <tsdgeos@yahoo.es>2019-03-31 00:33:09 +0000
commit516e6149572a16747f21d6510f844b5879954ec0 (patch)
tree766148818bfdc269e156360d38086a3072471e71
parentf25f7f19fab3559ecf2d427a52193767c02e2640 (diff)
Integer-overflow in Gfx::doAxialShFill
oss-fuzz/8631
-rw-r--r--goo/GooCheckedOps.h11
-rw-r--r--poppler/Gfx.cc21
2 files changed, 22 insertions, 10 deletions
diff --git a/goo/GooCheckedOps.h b/goo/GooCheckedOps.h
index 3da6b337..5eedf34b 100644
--- a/goo/GooCheckedOps.h
+++ b/goo/GooCheckedOps.h
@@ -5,6 +5,7 @@
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
+// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@gmail.com>
//
//========================================================================
@@ -12,6 +13,7 @@
#define GOO_CHECKED_OPS_H
#include <climits>
+#include <limits>
inline bool checkedAssign(long long lz, int *z) {
static_assert(LLONG_MAX > INT_MAX, "Need type larger than int to perform overflow checks.");
@@ -46,4 +48,13 @@ inline bool checkedMultiply(int x, int y, int *z) {
#endif
}
+template<typename T> inline T safeAverage(T a, T b) {
+ static_assert(std::numeric_limits<long long>::max() > std::numeric_limits<T>::max(),
+ "The max of long long type must be larger to perform overflow checks.");
+ static_assert(std::numeric_limits<long long>::min() < std::numeric_limits<T>::min(),
+ "The min of long long type must be smaller to perform overflow checks.");
+
+ return static_cast<T>((static_cast<long long>(a) + static_cast<long long>(b)) / 2);
+}
+
#endif // GOO_CHECKED_OPS_H
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index ef57e512..8bf141e9 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -41,6 +41,7 @@
// Copyright (C) 2017, 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018, 2019 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2018 Denis Onishchenko <denis.onischenko@gmail.com>
+// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@gmail.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -2809,7 +2810,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) {
// use the average of the colors of the two sides of the region
for (k = 0; k < nComps; ++k) {
- color0.c[k] = (color0.c[k] + color1.c[k]) / 2;
+ color0.c[k] = safeAverage(color0.c[k], color1.c[k]);
}
// compute the coordinates of the point on the t axis; then
@@ -3114,7 +3115,7 @@ void Gfx::doRadialShFill(GfxRadialShading *shading) {
// use the average of the colors at the two circles
for (k = 0; k < nComps; ++k) {
- colorA.c[k] = (colorA.c[k] + colorB.c[k]) / 2;
+ colorA.c[k] = safeAverage(colorA.c[k], colorB.c[k]);
}
state->setFillColor(&colorA);
if (out->useFillColorStop())
@@ -3357,9 +3358,9 @@ void Gfx::gouraudFillTriangle(double x0, double y0, GfxColor *color0,
x20 = 0.5 * (x2 + x0);
y20 = 0.5 * (y2 + y0);
for (i = 0; i < nComps; ++i) {
- color01.c[i] = (color0->c[i] + color1->c[i]) / 2;
- color12.c[i] = (color1->c[i] + color2->c[i]) / 2;
- color20.c[i] = (color2->c[i] + color0->c[i]) / 2;
+ color01.c[i] = safeAverage(color0->c[i], color1->c[i]);
+ color12.c[i] = safeAverage(color1->c[i], color2->c[i]);
+ color20.c[i] = safeAverage(color2->c[i], color0->c[i]);
}
gouraudFillTriangle(x0, y0, color0, x01, y01, &color01,
x20, y20, &color20, nComps, depth + 1, path);
@@ -3584,22 +3585,22 @@ void Gfx::fillPatch(const GfxPatch *patch, int colorComps, int patchColorComps,
for (i = 0; i < patchColorComps; ++i) {
patch00.color[0][0].c[i] = patch->color[0][0].c[i];
patch00.color[0][1].c[i] = (patch->color[0][0].c[i] +
- patch->color[0][1].c[i]) / 2;
+ patch->color[0][1].c[i]) / 2.;
patch01.color[0][0].c[i] = patch00.color[0][1].c[i];
patch01.color[0][1].c[i] = patch->color[0][1].c[i];
patch01.color[1][1].c[i] = (patch->color[0][1].c[i] +
- patch->color[1][1].c[i]) / 2;
+ patch->color[1][1].c[i]) / 2.;
patch11.color[0][1].c[i] = patch01.color[1][1].c[i];
patch11.color[1][1].c[i] = patch->color[1][1].c[i];
patch11.color[1][0].c[i] = (patch->color[1][1].c[i] +
- patch->color[1][0].c[i]) / 2;
+ patch->color[1][0].c[i]) / 2.;
patch10.color[1][1].c[i] = patch11.color[1][0].c[i];
patch10.color[1][0].c[i] = patch->color[1][0].c[i];
patch10.color[0][0].c[i] = (patch->color[1][0].c[i] +
- patch->color[0][0].c[i]) / 2;
+ patch->color[0][0].c[i]) / 2.;
patch00.color[1][0].c[i] = patch10.color[0][0].c[i];
patch00.color[1][1].c[i] = (patch00.color[1][0].c[i] +
- patch01.color[1][1].c[i]) / 2;
+ patch01.color[1][1].c[i]) / 2.;
patch01.color[1][0].c[i] = patch00.color[1][1].c[i];
patch11.color[0][0].c[i] = patch00.color[1][1].c[i];
patch10.color[0][1].c[i] = patch00.color[1][1].c[i];