From a8cbd5f114e8a06e540d0038103ea4d85d925658 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ra=C3=BAl=20Mar=C3=ADn=20Rodr=C3=ADguez?= Date: Wed, 21 Nov 2018 11:46:43 +0000 Subject: [PATCH] =?utf8?q?Avoid=20undefined=20behaviour=20in=20next=5Ffloa?= =?utf8?q?t=20functions=20(Ra=C3=BAl=20Mar=C3=ADn)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Closes #4247 Closes https://github.com/postgis/postgis/pull/339 git-svn-id: http://svn.osgeo.org/postgis/trunk@17038 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 1 + liblwgeom/cunit/cu_libgeom.c | 20 ++++++++++++++++++++ liblwgeom/lwgeom_api.c | 14 ++++++++++++-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index ac3ba0c70..9111d6d14 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,7 @@ PostGIS 3.0.0 - #4326, Allocate enough memory in gidx_to_string (Raúl Marín) - #4190, Avoid undefined behaviour in gserialized_estimate (Raúl Marín) - #4233, Fix undefined behaviour in gserialized_spgist_picksplit_nd (Raúl Marín) + - #4247, Avoid undefined behaviour in next_float functions (Raúl Marín) PostGIS 2.5.0 2018/09/23 diff --git a/liblwgeom/cunit/cu_libgeom.c b/liblwgeom/cunit/cu_libgeom.c index 55625d2ee..43c2c9907 100644 --- a/liblwgeom/cunit/cu_libgeom.c +++ b/liblwgeom/cunit/cu_libgeom.c @@ -688,6 +688,26 @@ static void test_f2d(void) f = next_float_up(d); d = next_float_up(f); CU_ASSERT_DOUBLE_EQUAL(f,d, 0.0000001); + + d = DBL_MAX; + f = next_float_up(d); + d = next_float_up(f); + CU_ASSERT_DOUBLE_EQUAL(f, d, 0.0000001); + + d = DBL_MAX; + f = next_float_down(d); + d = next_float_down(f); + CU_ASSERT_DOUBLE_EQUAL(f, d, 0.0000001); + + d = -DBL_MAX; + f = next_float_up(d); + d = next_float_up(f); + CU_ASSERT_DOUBLE_EQUAL(f, d, 0.0000001); + + d = -DBL_MAX; + f = next_float_down(d); + d = next_float_down(f); + CU_ASSERT_DOUBLE_EQUAL(f, d, 0.0000001); } /* diff --git a/liblwgeom/lwgeom_api.c b/liblwgeom/lwgeom_api.c index 27515ee5d..ac0dce80a 100644 --- a/liblwgeom/lwgeom_api.c +++ b/liblwgeom/lwgeom_api.c @@ -50,7 +50,12 @@ lwgeom_version() inline float next_float_down(double d) { - float result = d; + float result; + if (d > (double)FLT_MAX) + return FLT_MAX; + if (d <= (double)-FLT_MAX) + return -FLT_MAX; + result = d; if ( ((double)result) <=d ) return result; @@ -66,7 +71,12 @@ next_float_down(double d) inline float next_float_up(double d) { - float result = d; + float result; + if (d >= (double)FLT_MAX) + return FLT_MAX; + if (d < (double)-FLT_MAX) + return -FLT_MAX; + result = d; if ( ((double)result) >=d ) return result; -- 2.50.0