Merge branch 'PHP-8.3' into PHP-8.4

This commit is contained in:
David Carlier 2024-10-25 14:05:16 +01:00
commit 9ee204f2e3
No known key found for this signature in database
GPG Key ID: 8486F847B4B94EF1
5 changed files with 119 additions and 35 deletions

2
NEWS
View File

@ -84,6 +84,8 @@ PHP NEWS
. Fixed bug GH-16411 (gmp_export() can cause overflow). (cmb)
. Fixed bug GH-16501 (gmp_random_bits() can cause overflow).
(David Carlier)
. Fixed gmp_pow() overflow bug with large base/exponents.
(David Carlier)
- MBstring:
. Fixed bug GH-16361 (mb_substr overflow on start/length arguments).

View File

@ -1292,39 +1292,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);
}
}

View File

@ -2,6 +2,8 @@
gmp_pow() basic tests
--EXTENSIONS--
gmp
--SKIPIF--
<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); ?>
--FILE--
<?php

View File

@ -0,0 +1,77 @@
--TEST--
gmp_pow() basic tests
--EXTENSIONS--
gmp
--SKIPIF--
<?php if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); ?>
--FILE--
<?php
var_dump(gmp_strval(gmp_pow(2,10)));
var_dump(gmp_strval(gmp_pow(-2,10)));
var_dump(gmp_strval(gmp_pow(-2,11)));
var_dump(gmp_strval(gmp_pow("2",10)));
var_dump(gmp_strval(gmp_pow("2",0)));
try {
gmp_pow("2", -1);
} catch (ValueError $exception) {
echo $exception->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

View File

@ -6,15 +6,30 @@ gmp
<?php
$g = gmp_init(256);
var_dump(gmp_pow($g, PHP_INT_MAX));
var_dump(gmp_pow(256, PHP_INT_MAX));
try {
gmp_pow($g, PHP_INT_MAX);
} catch (\ValueError $e) {
echo $e->getMessage() . PHP_EOL;
}
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--
object(GMP)#2 (1) {
["num"]=>
string(%d) "%s"
}
object(GMP)#2 (1) {
["num"]=>
string(%d) "%s"
}
base and exponent overflow
base and exponent overflow
base and exponent overflow
base and exponent overflow