diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index ba62b37ad2c8a..42a4a446867c2 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1282,39 +1282,27 @@ ZEND_FUNCTION(gmp_pow) RETURN_THROWS(); } + double powmax = log((double)ZEND_LONG_MAX); + if (Z_TYPE_P(base_arg) == IS_LONG && Z_LVAL_P(base_arg) >= 0) { INIT_GMP_RETVAL(gmpnum_result); - 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); + if ((log(Z_LVAL_P(base_arg)) * exp) > powmax) { + zend_value_error("base and exponent overflow"); + RETURN_THROWS(); } + mpz_ui_pow_ui(gmpnum_result, Z_LVAL_P(base_arg), exp); } else { mpz_ptr gmpnum_base; + zend_ulong gmpnum; FETCH_GMP_ZVAL(gmpnum_base, base_arg, temp_base, 1); INIT_GMP_RETVAL(gmpnum_result); - 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); + gmpnum = mpz_get_ui(gmpnum_base); + if ((log(gmpnum) * exp) > powmax) { + FREE_GMP_TEMP(temp_base); + zend_value_error("base and exponent overflow"); + RETURN_THROWS(); } + mpz_pow_ui(gmpnum_result, gmpnum_base, exp); FREE_GMP_TEMP(temp_base); } } diff --git a/ext/gmp/tests/gmp_pow.phpt b/ext/gmp/tests/gmp_pow.phpt index f42e44e31abed..1d77bd5e96c80 100644 --- a/ext/gmp/tests/gmp_pow.phpt +++ b/ext/gmp/tests/gmp_pow.phpt @@ -2,6 +2,8 @@ gmp_pow() basic tests --EXTENSIONS-- gmp +--SKIPIF-- + --FILE-- +--FILE-- +getMessage() . "\n"; +} +var_dump(gmp_strval(gmp_pow("-2",10))); +try { + gmp_pow(20,10); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +try { + gmp_pow(50,10); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +try { + gmp_pow(50,-5); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +try { + $n = gmp_init("20"); + gmp_pow($n,10); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +try { + $n = gmp_init("-20"); + gmp_pow($n,10); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +try { + var_dump(gmp_pow(2,array())); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +try { + var_dump(gmp_pow(array(),10)); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo "Done\n"; +?> +--EXPECT-- +string(4) "1024" +string(4) "1024" +string(5) "-2048" +string(4) "1024" +string(1) "1" +gmp_pow(): Argument #2 ($exponent) must be greater than or equal to 0 +string(4) "1024" +base and exponent overflow +base and exponent overflow +gmp_pow(): Argument #2 ($exponent) must be greater than or equal to 0 +base and exponent overflow +base and exponent overflow +gmp_pow(): Argument #2 ($exponent) must be of type int, array given +gmp_pow(): Argument #1 ($num) must be of type GMP|string|int, array given +Done diff --git a/ext/gmp/tests/gmp_pow_fpe.phpt b/ext/gmp/tests/gmp_pow_fpe.phpt index d564853799c8d..248922e80514d 100644 --- a/ext/gmp/tests/gmp_pow_fpe.phpt +++ b/ext/gmp/tests/gmp_pow_fpe.phpt @@ -6,15 +6,30 @@ gmp ---EXPECTF-- -object(GMP)#2 (1) { - ["num"]=> - string(%d) "%s" +try { + gmp_pow($g, PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; } -object(GMP)#2 (1) { - ["num"]=> - string(%d) "%s" +try { + gmp_pow(256, PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; +} + +try { + gmp_pow(gmp_add(gmp_mul(gmp_init(PHP_INT_MAX), gmp_init(PHP_INT_MAX)), 3), 256); +} catch (\ValueError $e) { + echo $e->getMessage() . PHP_EOL; } +try { + gmp_pow(gmp_init(PHP_INT_MAX), 256); +} catch (\ValueError $e) { + echo $e->getMessage(); +} +?> +--EXPECTF-- +base and exponent overflow +base and exponent overflow +base and exponent overflow +base and exponent overflow