[poppler] goo/GooCheckedOps.h poppler/Gfx.cc

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Mar 31 00:33:12 UTC 2019


 goo/GooCheckedOps.h |   11 +++++++++++
 poppler/Gfx.cc      |   21 +++++++++++----------
 2 files changed, 22 insertions(+), 10 deletions(-)

New commits:
commit 516e6149572a16747f21d6510f844b5879954ec0
Author: LE GARREC Vincent <gitlab-freedesktop at le-garrec.fr>
Date:   Sun Mar 31 00:33:09 2019 +0000

    Integer-overflow in Gfx::doAxialShFill
    
    oss-fuzz/8631

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 at t-online.de>
+// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent at 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 at kdab.com>. Work sponsored by the LiMux project of the city of Munich
 // Copyright (C) 2018, 2019 Adam Reichold <adam.reichold at t-online.de>
 // Copyright (C) 2018 Denis Onishchenko <denis.onischenko at gmail.com>
+// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent at 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];


More information about the poppler mailing list