From bcb89c75ece71869c99032e078e0ec4fe12b2645 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 16 Jul 2021 14:49:25 +0200 Subject: [PATCH] Fix #78238: BCMath returns "-0" There is no negative zero in the decimal system, so we must suppress the sign. Closes GH-7250. --- NEWS | 3 +++ ext/bcmath/libbcmath/src/bcmath.h | 2 ++ ext/bcmath/libbcmath/src/num2str.c | 2 +- ext/bcmath/libbcmath/src/zero.c | 10 ++++++++-- ext/bcmath/tests/bug78238.phpt | 18 ++++++++++++++++++ 5 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 ext/bcmath/tests/bug78238.phpt diff --git a/NEWS b/NEWS index 7d049b33c30..a60fdf79234 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,9 @@ PHP NEWS - Core: . Fixed bug #72595 (php_output_handler_append illegal write access). (cmb) +- BCMath: + . Fixed bug #78238 (BCMath returns "-0"). (cmb) + - CGI: . Fixed bug #80849 (HTTP Status header truncation). (cmb) diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index becba7ec3e2..74e9fbc7a99 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -120,6 +120,8 @@ _PROTOTYPE(int bc_compare, (bc_num n1, bc_num n2)); _PROTOTYPE(char bc_is_zero, (bc_num num)); +_PROTOTYPE(char bc_is_zero_for_scale, (bc_num num, int scale)); + _PROTOTYPE(char bc_is_near_zero, (bc_num num, int scale)); _PROTOTYPE(char bc_is_neg, (bc_num num)); diff --git a/ext/bcmath/libbcmath/src/num2str.c b/ext/bcmath/libbcmath/src/num2str.c index 23988c0d6c5..546e87a22fd 100644 --- a/ext/bcmath/libbcmath/src/num2str.c +++ b/ext/bcmath/libbcmath/src/num2str.c @@ -50,7 +50,7 @@ zend_string int index, signch; /* Allocate the string memory. */ - signch = num->n_sign != PLUS; /* Number of sign chars. */ + signch = num->n_sign != PLUS && !bc_is_zero_for_scale(num, MIN(num->n_scale, scale)); /* Number of sign chars. */ if (scale > 0) str = zend_string_alloc(num->n_len + scale + signch + 1, 0); else diff --git a/ext/bcmath/libbcmath/src/zero.c b/ext/bcmath/libbcmath/src/zero.c index 28038201242..ba188d04369 100644 --- a/ext/bcmath/libbcmath/src/zero.c +++ b/ext/bcmath/libbcmath/src/zero.c @@ -40,7 +40,7 @@ /* In some places we need to check if the number NUM is zero. */ char -bc_is_zero (bc_num num) +bc_is_zero_for_scale (bc_num num, int scale) { int count; char *nptr; @@ -49,7 +49,7 @@ bc_is_zero (bc_num num) if (num == BCG(_zero_)) return TRUE; /* Initialize */ - count = num->n_len + num->n_scale; + count = num->n_len + scale; nptr = num->n_value; /* The check */ @@ -60,3 +60,9 @@ bc_is_zero (bc_num num) else return TRUE; } + +char +bc_is_zero (bc_num num) +{ + return bc_is_zero_for_scale(num, num->n_scale); +} diff --git a/ext/bcmath/tests/bug78238.phpt b/ext/bcmath/tests/bug78238.phpt new file mode 100644 index 00000000000..6752f45a7db --- /dev/null +++ b/ext/bcmath/tests/bug78238.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #78238 (BCMath returns "-0") +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(1) "0" +string(3) "0.0" +string(3) "0.0"