diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2017-09-18 15:04:44 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2017-09-18 15:21:22 +0200 |
commit | 73af7a847c5f08d32802d41fc45ed4b01ec9fb9c (patch) | |
tree | 528ea68ade394772d0640509eab2104cefb24efe /ext/bcmath | |
parent | f63bfea105cd2d1285a1189c197d8371cad5f403 (diff) | |
parent | 870ed5106d6274905b5aa4341429deef12c92e55 (diff) | |
download | php-git-73af7a847c5f08d32802d41fc45ed4b01ec9fb9c.tar.gz |
Merge branch 'pull-request/2742'
* pull-request/2742:
Fixed bug #66364 (BCMath bcmul ignores scale parameter)
Diffstat (limited to 'ext/bcmath')
-rw-r--r-- | ext/bcmath/bcmath.c | 61 | ||||
-rw-r--r-- | ext/bcmath/libbcmath/src/bcmath.h | 3 | ||||
-rw-r--r-- | ext/bcmath/libbcmath/src/num2str.c | 13 | ||||
-rw-r--r-- | ext/bcmath/tests/bcpow.phpt | 2 | ||||
-rw-r--r-- | ext/bcmath/tests/bcpow_error1.phpt | 2 | ||||
-rw-r--r-- | ext/bcmath/tests/bcpow_error2.phpt | 2 | ||||
-rw-r--r-- | ext/bcmath/tests/bug.66364.phpt | 14 | ||||
-rw-r--r-- | ext/bcmath/tests/scale.phpt | 27 | ||||
-rw-r--r-- | ext/bcmath/tests/scale_ini.phpt | 29 |
9 files changed, 90 insertions, 63 deletions
diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 8b3e3d9514..1186241620 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -207,21 +207,6 @@ static void php_str2num(bc_num *num, char *str) } /* }}} */ -/* {{{ split_bc_num - Convert to bc_num detecting scale */ -static bc_num split_bc_num(bc_num num) { - bc_num newnum; - if (num->n_refs >= 1) { - return num; - } - newnum = _bc_new_num_ex(0, 0, 0); - *newnum = *num; - newnum->n_refs = 1; - num->n_refs--; - return newnum; -} -/* }}} */ - /* {{{ proto string bcadd(string left_operand, string right_operand [, int scale]) Returns the sum of two arbitrary precision numbers */ PHP_FUNCTION(bcadd) @@ -249,12 +234,7 @@ PHP_FUNCTION(bcadd) php_str2num(&second, ZSTR_VAL(right)); bc_add (first, second, &result, scale); - if (result->n_scale > scale) { - result = split_bc_num(result); - result->n_scale = scale; - } - - RETVAL_STR(bc_num2str(result)); + RETVAL_STR(bc_num2str_ex(result, scale)); bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); @@ -289,12 +269,7 @@ PHP_FUNCTION(bcsub) php_str2num(&second, ZSTR_VAL(right)); bc_sub (first, second, &result, scale); - if (result->n_scale > scale) { - result = split_bc_num(result); - result->n_scale = scale; - } - - RETVAL_STR(bc_num2str(result)); + RETVAL_STR(bc_num2str_ex(result, scale)); bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); @@ -329,12 +304,7 @@ PHP_FUNCTION(bcmul) php_str2num(&second, ZSTR_VAL(right)); bc_multiply (first, second, &result, scale); - if (result->n_scale > scale) { - result = split_bc_num(result); - result->n_scale = scale; - } - - RETVAL_STR(bc_num2str(result)); + RETVAL_STR(bc_num2str_ex(result, scale)); bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); @@ -370,11 +340,7 @@ PHP_FUNCTION(bcdiv) switch (bc_divide(first, second, &result, scale)) { case 0: /* OK */ - if (result->n_scale > scale) { - result = split_bc_num(result); - result->n_scale = scale; - } - RETVAL_STR(bc_num2str(result)); + RETVAL_STR(bc_num2str_ex(result, scale)); break; case -1: /* division by zero */ php_error_docref(NULL, E_WARNING, "Division by zero"); @@ -450,11 +416,7 @@ PHP_FUNCTION(bcpowmod) scale_int = (int) ((int)scale < 0 ? 0 : scale); if (bc_raisemod(first, second, mod, &result, scale_int) != -1) { - if (result->n_scale > scale_int) { - result = split_bc_num(result); - result->n_scale = scale_int; - } - RETVAL_STR(bc_num2str(result)); + RETVAL_STR(bc_num2str_ex(result, scale_int)); } else { RETVAL_FALSE; } @@ -494,12 +456,7 @@ PHP_FUNCTION(bcpow) php_str2num(&second, ZSTR_VAL(right)); bc_raise (first, second, &result, scale); - if (result->n_scale > scale) { - result = split_bc_num(result); - result->n_scale = scale; - } - - RETVAL_STR(bc_num2str(result)); + RETVAL_STR(bc_num2str_ex(result, scale)); bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); @@ -530,11 +487,7 @@ PHP_FUNCTION(bcsqrt) php_str2num(&result, ZSTR_VAL(left)); if (bc_sqrt (&result, scale) != 0) { - if (result->n_scale > scale) { - result = split_bc_num(result); - result->n_scale = scale; - } - RETVAL_STR(bc_num2str(result)); + RETVAL_STR(bc_num2str_ex(result, scale)); } else { php_error_docref(NULL, E_WARNING, "Square root of negative number"); } diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index f0ab49fc52..78868edcb3 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -110,7 +110,7 @@ _PROTOTYPE(void bc_init_num, (bc_num *num)); _PROTOTYPE(void bc_str2num, (bc_num *num, char *str, int scale)); -_PROTOTYPE(zend_string *bc_num2str, (bc_num num)); +_PROTOTYPE(zend_string *bc_num2str_ex, (bc_num num, int scale)); _PROTOTYPE(void bc_int2num, (bc_num *num, int val)); @@ -155,5 +155,6 @@ _PROTOTYPE(void bc_out_of_memory, (void)); #define bc_new_num(length, scale) _bc_new_num_ex((length), (scale), 0) #define bc_free_num(num) _bc_free_num_ex((num), 0) +#define bc_num2str(num) bc_num2str_ex((num), (num->n_scale)) #endif diff --git a/ext/bcmath/libbcmath/src/num2str.c b/ext/bcmath/libbcmath/src/num2str.c index c72a924933..7316d32a14 100644 --- a/ext/bcmath/libbcmath/src/num2str.c +++ b/ext/bcmath/libbcmath/src/num2str.c @@ -41,8 +41,9 @@ /* Convert a numbers to a string. Base 10 only.*/ zend_string -*bc_num2str (num) +*bc_num2str_ex (num, scale) bc_num num; + int scale; { zend_string *str; char *sptr; @@ -51,8 +52,8 @@ zend_string /* Allocate the string memory. */ signch = ( num->n_sign == PLUS ? 0 : 1 ); /* Number of sign chars. */ - if (num->n_scale > 0) - str = zend_string_alloc(num->n_len + num->n_scale + signch + 1, 0); + if (scale > 0) + str = zend_string_alloc(num->n_len + scale + signch + 1, 0); else str = zend_string_alloc(num->n_len + signch, 0); if (str == NULL) bc_out_of_memory(); @@ -67,11 +68,13 @@ zend_string *sptr++ = BCD_CHAR(*nptr++); /* Now the fraction. */ - if (num->n_scale > 0) + if (scale > 0) { *sptr++ = '.'; - for (index=0; index<num->n_scale; index++) + for (index=0; index<scale && index<num->n_scale; index++) *sptr++ = BCD_CHAR(*nptr++); + for (index = num->n_scale; index<scale; index++) + *sptr++ = BCD_CHAR(0); } /* Terminate the string and return it! */ diff --git a/ext/bcmath/tests/bcpow.phpt b/ext/bcmath/tests/bcpow.phpt index 141ec61d92..ad642a57be 100644 --- a/ext/bcmath/tests/bcpow.phpt +++ b/ext/bcmath/tests/bcpow.phpt @@ -13,6 +13,6 @@ echo bcpow("-2.555", "5", 2),"\n"; ?> --EXPECT-- 1 --32 +-32.0000 18446744073709551616 -108.88 diff --git a/ext/bcmath/tests/bcpow_error1.phpt b/ext/bcmath/tests/bcpow_error1.phpt index 1075986587..d3189f062a 100644 --- a/ext/bcmath/tests/bcpow_error1.phpt +++ b/ext/bcmath/tests/bcpow_error1.phpt @@ -11,5 +11,5 @@ var_dump(bcpow('1', '1.1', 2)); ===DONE=== --EXPECTF-- Warning: bcpow(): non-zero scale in exponent in %s on line %d -string(1) "1" +string(4) "1.00" ===DONE=== diff --git a/ext/bcmath/tests/bcpow_error2.phpt b/ext/bcmath/tests/bcpow_error2.phpt index c58a737087..49fd0b88d3 100644 --- a/ext/bcmath/tests/bcpow_error2.phpt +++ b/ext/bcmath/tests/bcpow_error2.phpt @@ -11,5 +11,5 @@ var_dump(bcpow('0', '9223372036854775808', 2)); ===DONE=== --EXPECTF-- Warning: bcpow(): exponent too large in %s on line %d -string(1) "1" +string(4) "1.00" ===DONE=== diff --git a/ext/bcmath/tests/bug.66364.phpt b/ext/bcmath/tests/bug.66364.phpt new file mode 100644 index 0000000000..564f40e6da --- /dev/null +++ b/ext/bcmath/tests/bug.66364.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #66364 (BCMath bcmul ignores scale parameter) +--SKIPIF-- +<?php +if (!extension_loaded('bcmath')) die('skip bcmath extension not available'); +?> +--FILE-- +<?php +var_dump(bcmul('0.3', '0.2', 4)); +?> +===DONE=== +--EXPECT-- +string(6) "0.0600" +===DONE=== diff --git a/ext/bcmath/tests/scale.phpt b/ext/bcmath/tests/scale.phpt new file mode 100644 index 0000000000..d49e530511 --- /dev/null +++ b/ext/bcmath/tests/scale.phpt @@ -0,0 +1,27 @@ +--TEST-- +BCMath functions return result with requested scale +--SKIPIF-- +<?php +if (!extension_loaded('bcmath')) die('skip bcmath extension not available'); +?> +--FILE-- +<?php +echo + 'bcadd: ', bcadd('2', '1', 5), PHP_EOL, + 'bcdiv: ', bcdiv('2', '1', 5), PHP_EOL, + 'bcmul: ', bcmul('2', '1', 5), PHP_EOL, + 'bcpow: ', bcpow('2', '1', 5), PHP_EOL, + 'bcpowmod: ', bcpowmod('2', '1', '3', 5), PHP_EOL, + 'bcsqrt: ', bcsqrt('4', 5), PHP_EOL, + 'bcsub: ', bcsub('2', '1', 5), PHP_EOL; +?> +===DONE=== +--EXPECT-- +bcadd: 3.00000 +bcdiv: 2.00000 +bcmul: 2.00000 +bcpow: 2.00000 +bcpowmod: 2.00000 +bcsqrt: 2.00000 +bcsub: 1.00000 +===DONE=== diff --git a/ext/bcmath/tests/scale_ini.phpt b/ext/bcmath/tests/scale_ini.phpt new file mode 100644 index 0000000000..66d9d482bf --- /dev/null +++ b/ext/bcmath/tests/scale_ini.phpt @@ -0,0 +1,29 @@ +--TEST-- +BCMath functions return result with default scale +--SKIPIF-- +<?php +if (!extension_loaded('bcmath')) die('skip bcmath extension not available'); +?> +--INI-- +bcmath.scale = 5 +--FILE-- +<?php +echo + 'bcadd: ', bcadd('2', '1'), PHP_EOL, + 'bcdiv: ', bcdiv('2', '1'), PHP_EOL, + 'bcmul: ', bcmul('2', '1'), PHP_EOL, + 'bcpow: ', bcpow('2', '1'), PHP_EOL, + 'bcpowmod: ', bcpowmod('2', '1', '3'), PHP_EOL, + 'bcsqrt: ', bcsqrt('4'), PHP_EOL, + 'bcsub: ', bcsub('2', '1'), PHP_EOL; +?> +===DONE=== +--EXPECT-- +bcadd: 3.00000 +bcdiv: 2.00000 +bcmul: 2.00000 +bcpow: 2.00000 +bcpowmod: 2.00000 +bcsqrt: 2.00000 +bcsub: 1.00000 +===DONE=== |