diff --git a/NEWS b/NEWS index 6339158db93..88990f42a60 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,10 @@ PHP NEWS . Fixed bug GH-16334 (imageaffine overflow on matrix elements). (David Carlier) +- GMP: + . Fixed floating point exception bug with gmp_pow when using + large exposant values. (David Carlier). + - MBstring: . Fixed bug GH-16361 (mb_substr overflow on start/length arguments). (David Carlier) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 04bfafe8691..1bed437b93a 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1288,12 +1288,37 @@ ZEND_FUNCTION(gmp_pow) if (Z_TYPE_P(base_arg) == IS_LONG && Z_LVAL_P(base_arg) >= 0) { INIT_GMP_RETVAL(gmpnum_result); - mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp); + if (exp >= INT_MAX) { + mpz_t base_num, exp_num, mod; + mpz_init(base_num); + mpz_init(exp_num); + mpz_init(mod); + mpz_set_si(base_num, Z_LVAL_P(base_arg)); + mpz_set_si(exp_num, exp); + mpz_set_ui(mod, UINT_MAX); + mpz_powm(gmpnum_result, base_num, exp_num, mod); + mpz_clear(mod); + mpz_clear(exp_num); + mpz_clear(base_num); + } else { + mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp); + } } else { mpz_ptr gmpnum_base; FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base, 1); INIT_GMP_RETVAL(gmpnum_result); - mpz_pow_ui(gmpnum_result, gmpnum_base, exp); + if (exp >= INT_MAX) { + mpz_t exp_num, mod; + mpz_init(exp_num); + mpz_init(mod); + mpz_set_si(exp_num, exp); + mpz_set_ui(mod, UINT_MAX); + mpz_powm(gmpnum_result, gmpnum_base, exp_num, mod); + mpz_clear(mod); + mpz_clear(exp_num); + } else { + mpz_pow_ui(gmpnum_result, gmpnum_base, exp); + } FREE_GMP_TEMP(temp_base); } } diff --git a/ext/gmp/tests/gmp_pow_fpe.phpt b/ext/gmp/tests/gmp_pow_fpe.phpt new file mode 100644 index 00000000000..d564853799c --- /dev/null +++ b/ext/gmp/tests/gmp_pow_fpe.phpt @@ -0,0 +1,20 @@ +--TEST-- +gmp_pow() floating point exception +--EXTENSIONS-- +gmp +--FILE-- + +--EXPECTF-- +object(GMP)#2 (1) { + ["num"]=> + string(%d) "%s" +} +object(GMP)#2 (1) { + ["num"]=> + string(%d) "%s" +}