From 665050787c18a5d09f1b6d1443efbad901b9ac0b Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Tue, 26 Jul 2016 21:57:07 -0700 Subject: [PATCH] Bugfix#70896 gmp_fact() silently ignores non-integer inputs Factorials only make sense for integer inputs. To do something factorial-like, the Gamma Function should be used instead. However, at this point it's no longer a factorial. For PHP/GMP, we'll raise a warning on trying to use a non-integer input, but carry on returning the truncated value as we used to (avoiding BC breakage). --- NEWS | 3 +++ ext/gmp/gmp.c | 11 ++++++++++- ext/gmp/tests/gmp_fact.phpt | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 317f73c5c8..7b1e2d4bae 100644 --- a/NEWS +++ b/NEWS @@ -2,4 +2,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2016, PHP 7.2.0alpha1 +- GMP: + . Fixed bug #70896 (gmp_fact() silently ignores non-integer input). (Sara) + <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 30693da5cb..ea3c6cf408 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1365,7 +1365,16 @@ ZEND_FUNCTION(gmp_fact) RETURN_FALSE; } } else { - if (zval_get_long(a_arg) < 0) { + /* Use convert_to_number first to detect getting non-integer */ + convert_scalar_to_number(a_arg); + if (Z_TYPE_P(a_arg) != IS_LONG) { + convert_to_long(a_arg); + if (Z_LVAL_P(a_arg) >= 0) { + /* Only warn if we'll make it past the non-negative check */ + php_error_docref(NULL, E_WARNING, "Number has to be an integer"); + } + } + if (Z_LVAL_P(a_arg) < 0) { php_error_docref(NULL, E_WARNING, "Number has to be greater than or equal to 0"); RETURN_FALSE; } diff --git a/ext/gmp/tests/gmp_fact.phpt b/ext/gmp/tests/gmp_fact.phpt index 6afccaf936..5cb8089b49 100644 --- a/ext/gmp/tests/gmp_fact.phpt +++ b/ext/gmp/tests/gmp_fact.phpt @@ -38,6 +38,8 @@ string(1) "0" Warning: gmp_fact(): Number has to be greater than or equal to 0 in %s on line %d string(1) "0" + +Warning: gmp_fact(): Number has to be an integer in %s on line %d string(1) "1" string(19) "2432902008176640000" string(65) "30414093201713378043612608166064768844377641568960512000000000000" @@ -53,9 +55,13 @@ NULL Warning: gmp_fact() expects exactly 1 parameter, 2 given in %s on line %d NULL + +Warning: gmp_fact(): Number has to be an integer in %s on line %d object(GMP)#%d (1) { ["num"]=> string(1) "1" } + +Warning: gmp_fact(): Number has to be an integer in %s on line %d string(1) "1" Done -- 2.40.0