From: Joseph Myers Date: Wed, 21 Aug 2013 19:56:48 +0000 (+0000) Subject: Fix fdim handling of infinities (bug 15797). X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c3a4bddd656561cfffba2605e148e65d4ff07e21;p=thirdparty%2Fglibc.git Fix fdim handling of infinities (bug 15797). --- diff --git a/ChangeLog b/ChangeLog index 16e258c8adb..7b4d6e9214a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2013-08-21 Joseph Myers + + [BZ #15797] + * math/s_fdim.c (__fdim): Check for infinite arguments if result + is infinite, not alongside NaN test. + * math/s_fdimf.c (__fdimf): Likewise. + * math/s_fdiml.c (__fdiml): Likewise. + * math/libm-test.inc (fdim_test_data): Add more tests. Test that + errno is unchanged. + 2013-07-23 Adhemerval Zanella [BZ #15867] diff --git a/NEWS b/NEWS index ab3f353b83b..0d0a315da51 100644 --- a/NEWS +++ b/NEWS @@ -22,7 +22,7 @@ Version 2.18 15424, 15426, 15429, 15431, 15432, 15441, 15442, 15448, 15465, 15480, 15485, 15488, 15490, 15492, 15493, 15497, 15506, 15529, 15536, 15553, 15577, 15583, 15618, 15627, 15631, 15654, 15655, 15666, 15667, 15674, - 15711, 15755, 15759. + 15711, 15755, 15759, 15797. * CVE-2013-2207 Incorrectly granting access to another user's pseudo-terminal has been fixed by disabling the use of pt_chown (Bugzilla #15755). diff --git a/math/libm-test.inc b/math/libm-test.inc index 3b382af1049..8c1dcac8e8a 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -8139,33 +8139,37 @@ fabs_test (void) static const struct test_ff_f_data fdim_test_data[] = { - TEST_ff_f (fdim, 0, 0, 0, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, 9, 0, 9, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, 0, 9, 0, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, -9, 0, 0, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, 0, -9, 9, NO_INEXACT_EXCEPTION), - - TEST_ff_f (fdim, plus_infty, 9, plus_infty, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, plus_infty, -9, plus_infty, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, minus_infty, 9, 0, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, minus_infty, -9, 0, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, 9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, -9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, 9, plus_infty, 0, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, -9, plus_infty, 0, NO_INEXACT_EXCEPTION), - - TEST_ff_f (fdim, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, 9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, -9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, qnan_value, 9, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, qnan_value, -9, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION), - TEST_ff_f (fdim, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION), - - TEST_ff_f (fdim, plus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION), + TEST_ff_f (fdim, 0, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, 9, 0, 9, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, 0, 9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, -9, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, 0, -9, 9, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + + TEST_ff_f (fdim, plus_infty, 9, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, plus_infty, -9, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, minus_infty, 9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, minus_infty, -9, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, 9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, -9, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, 9, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, -9, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + + TEST_ff_f (fdim, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, 9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, -9, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, qnan_value, 9, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, qnan_value, -9, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + + TEST_ff_f (fdim, plus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, plus_infty, minus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, minus_infty, plus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_ff_f (fdim, minus_infty, minus_infty, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), }; static void diff --git a/math/s_fdim.c b/math/s_fdim.c index 2f97948b2ea..f8fd80490d5 100644 --- a/math/s_fdim.c +++ b/math/s_fdim.c @@ -26,16 +26,16 @@ __fdim (double x, double y) int clsx = fpclassify (x); int clsy = fpclassify (y); - if (clsx == FP_NAN || clsy == FP_NAN - || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE)) - /* Raise invalid flag. */ + if (clsx == FP_NAN || clsy == FP_NAN) + /* Raise invalid flag for signaling but not quiet NaN. */ return x - y; if (x <= y) return 0.0; double r = x - y; - if (fpclassify (r) == FP_INFINITE) + if (fpclassify (r) == FP_INFINITE + && clsx != FP_INFINITE && clsy != FP_INFINITE) __set_errno (ERANGE); return r; diff --git a/math/s_fdimf.c b/math/s_fdimf.c index 03810b57284..86efe6ef2ac 100644 --- a/math/s_fdimf.c +++ b/math/s_fdimf.c @@ -26,16 +26,16 @@ __fdimf (float x, float y) int clsx = fpclassify (x); int clsy = fpclassify (y); - if (clsx == FP_NAN || clsy == FP_NAN - || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE)) - /* Raise invalid flag. */ + if (clsx == FP_NAN || clsy == FP_NAN) + /* Raise invalid flag for signaling but not quiet NaN. */ return x - y; if (x <= y) return 0.0f; float r = x - y; - if (fpclassify (r) == FP_INFINITE) + if (fpclassify (r) == FP_INFINITE + && clsx != FP_INFINITE && clsy != FP_INFINITE) __set_errno (ERANGE); return r; diff --git a/math/s_fdiml.c b/math/s_fdiml.c index 56045329afe..030fcc22e68 100644 --- a/math/s_fdiml.c +++ b/math/s_fdiml.c @@ -26,16 +26,16 @@ __fdiml (long double x, long double y) int clsx = fpclassify (x); int clsy = fpclassify (y); - if (clsx == FP_NAN || clsy == FP_NAN - || (y < 0 && clsx == FP_INFINITE && clsy == FP_INFINITE)) - /* Raise invalid flag. */ + if (clsx == FP_NAN || clsy == FP_NAN) + /* Raise invalid flag for signaling but not quiet NaN. */ return x - y; if (x <= y) return 0.0f; long double r = x - y; - if (fpclassify (r) == FP_INFINITE) + if (fpclassify (r) == FP_INFINITE + && clsx != FP_INFINITE && clsy != FP_INFINITE) __set_errno (ERANGE); return r;