From fe01efca4e02d4ded4b397c6dcd0cd8ab8f6123a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Mar 2019 19:55:46 +0100 Subject: isea: detect various int overflows and div by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2199 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2241 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2390 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7674 Credit to OSS Fuzz --- src/projections/isea.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index fc74bebe..659ca790 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -10,6 +10,8 @@ #include #include +#include + #define PJ_LIB__ #include "proj_internal.h" #include "proj_math.h" @@ -89,6 +91,9 @@ static void hexbin2(double width, double x, double y, long *i, long *j) { y = y - x / 2.0; /* adjustment for rotated X */ /* adjust for actual hexwidth */ + if( width == 0 ) { + throw "Division by zero"; + } x /= width; y /= width; @@ -100,6 +105,9 @@ static void hexbin2(double width, double x, double y, long *i, long *j) { iy = lround(ry); rz = floor(z + 0.5); iz = lround(rz); + if( fabs(rx + ry + rz) > std::numeric_limits::max() ) { + throw "Integer overflow"; + } s = ix + iy + iz; @@ -764,11 +772,18 @@ static int isea_dddi(struct isea_dgg *g, int quad, struct isea_pt *pt, } /* todo might want to do this as an iterated loop */ if (g->aperture >0) { - sidelength = lround(pow(g->aperture, g->resolution / 2.0)); + double sidelengthDouble = pow(g->aperture, g->resolution / 2.0); + if( fabs(sidelengthDouble) > std::numeric_limits::max() ) { + throw "Integer overflow"; + } + sidelength = lround(sidelengthDouble); } else { sidelength = g->resolution; } + if( sidelength == 0 ) { + throw "Division by zero"; + } hexwidth = 1.0 / sidelength; v = *pt; @@ -1004,7 +1019,12 @@ static PJ_XY s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ in.lon = lp.lam; in.lat = lp.phi; - out = isea_forward(&Q->dgg, &in); + try { + out = isea_forward(&Q->dgg, &in); + } catch( const char* ) { + proj_errno_set(P, PJD_ERR_NON_CONVERGENT); + return proj_coord_error().xy; + } xy.x = out.x; xy.y = out.y; -- cgit v1.2.3