mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Implement GMP::__construct()
Implements a proper constructor for GMP as discussed in both GH-10158 and https://externals.io/message/119216. Fixes GH-10155 Closes GH-10225 Signed-off-by: George Peter Banyard <girgias@php.net>
This commit is contained in:
parent
148ac364e9
commit
4ea85d4044
3
NEWS
3
NEWS
@ -5,6 +5,9 @@ PHP NEWS
|
||||
- Core:
|
||||
. Fixed incorrect check condition in ZEND_YIELD. (nielsdos)
|
||||
|
||||
- GMP:
|
||||
. Properly implement GMP::__construct(). (nielsdos)
|
||||
|
||||
02 Feb 2023, PHP 8.2.2
|
||||
|
||||
- Core:
|
||||
|
@ -104,6 +104,10 @@ PHP 8.2 UPGRADE NOTES
|
||||
flags to determine if it should create a sub directory or not when creating
|
||||
a database file.
|
||||
|
||||
- GMP:
|
||||
. GMP::__construct() can now be used instead of gmp_init() to initialize an object (Only as of PHP 8.2.3)
|
||||
|
||||
|
||||
- OCI8:
|
||||
. Added an oci8.prefetch_lob_size directive and oci_set_prefetch_lob()
|
||||
function to tune LOB query performance by reducing the number of
|
||||
|
@ -862,6 +862,26 @@ static inline void _gmp_unary_opl(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_opl_t
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static bool gmp_verify_base(zend_long base, uint32_t arg_num)
|
||||
{
|
||||
if (base && (base < 2 || base > GMP_MAX_BASE)) {
|
||||
zend_argument_value_error(arg_num, "must be between 2 and %d", GMP_MAX_BASE);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static zend_result gmp_initialize_number(mpz_ptr gmp_number, const zend_string *arg_str, zend_long arg_l, zend_long base)
|
||||
{
|
||||
if (arg_str) {
|
||||
return convert_zstr_to_gmp(gmp_number, arg_str, base, 1);
|
||||
}
|
||||
|
||||
mpz_set_si(gmp_number, arg_l);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* {{{ Initializes GMP number */
|
||||
ZEND_FUNCTION(gmp_init)
|
||||
{
|
||||
@ -876,18 +896,14 @@ ZEND_FUNCTION(gmp_init)
|
||||
Z_PARAM_LONG(base)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (base && (base < 2 || base > GMP_MAX_BASE)) {
|
||||
zend_argument_value_error(2, "must be between 2 and %d", GMP_MAX_BASE);
|
||||
if (!gmp_verify_base(base, 2)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
INIT_GMP_RETVAL(gmp_number);
|
||||
if (arg_str) {
|
||||
if (convert_zstr_to_gmp(gmp_number, arg_str, base, 1) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
} else {
|
||||
mpz_set_si(gmp_number, arg_l);
|
||||
|
||||
if (gmp_initialize_number(gmp_number, arg_str, arg_l, base) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -2021,6 +2037,30 @@ ZEND_FUNCTION(gmp_scan1)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_METHOD(GMP, __construct)
|
||||
{
|
||||
zend_string *arg_str = NULL;
|
||||
zend_long arg_l = 0;
|
||||
zend_long base = 0;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(0, 2)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_STR_OR_LONG(arg_str, arg_l)
|
||||
Z_PARAM_LONG(base)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (!gmp_verify_base(base, 2)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
return_value = ZEND_THIS;
|
||||
mpz_ptr gmp_number = GET_GMP_FROM_ZVAL(ZEND_THIS);
|
||||
|
||||
if (gmp_initialize_number(gmp_number, arg_str, arg_l, base) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_METHOD(GMP, __serialize)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
@ -59,6 +59,8 @@ const GMP_NATIVE_ENDIAN = UNKNOWN;
|
||||
|
||||
class GMP
|
||||
{
|
||||
public function __construct(int|string $num = 0, int $base = 0) {}
|
||||
|
||||
public function __serialize(): array {}
|
||||
|
||||
public function __unserialize(array $data): void {}
|
||||
|
9
ext/gmp/gmp_arginfo.h
generated
9
ext/gmp/gmp_arginfo.h
generated
@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 64a40a366b87a96a291de6a474e60c8d98d15da1 */
|
||||
* Stub hash: d52f82c7084a8122fe07c91eb6d4ab6030daa27d */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_gmp_init, 0, 1, GMP, 0)
|
||||
ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_STRING, NULL)
|
||||
@ -184,6 +184,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_gmp_binomial, 0, 2, GMP, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, k, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_GMP___construct, 0, 0, 0)
|
||||
ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_STRING, "0")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, base, IS_LONG, 0, "0")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_GMP___serialize, 0, 0, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
@ -242,6 +247,7 @@ ZEND_FUNCTION(gmp_popcount);
|
||||
ZEND_FUNCTION(gmp_hamdist);
|
||||
ZEND_FUNCTION(gmp_nextprime);
|
||||
ZEND_FUNCTION(gmp_binomial);
|
||||
ZEND_METHOD(GMP, __construct);
|
||||
ZEND_METHOD(GMP, __serialize);
|
||||
ZEND_METHOD(GMP, __unserialize);
|
||||
|
||||
@ -303,6 +309,7 @@ static const zend_function_entry ext_functions[] = {
|
||||
|
||||
|
||||
static const zend_function_entry class_GMP_methods[] = {
|
||||
ZEND_ME(GMP, __construct, arginfo_class_GMP___construct, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(GMP, __serialize, arginfo_class_GMP___serialize, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(GMP, __unserialize, arginfo_class_GMP___unserialize, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
|
51
ext/gmp/tests/construct.phpt
Normal file
51
ext/gmp/tests/construct.phpt
Normal file
@ -0,0 +1,51 @@
|
||||
--TEST--
|
||||
Constructor for GMP
|
||||
--EXTENSIONS--
|
||||
gmp
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(new GMP);
|
||||
var_dump(new GMP(0));
|
||||
var_dump(new GMP(123));
|
||||
var_dump(new GMP("0xAA"));
|
||||
var_dump(new GMP("12", 4));
|
||||
try {
|
||||
var_dump(new GMP("12", 999));
|
||||
} catch (ValueError $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
try {
|
||||
var_dump(new GMP("", 10));
|
||||
} catch (ValueError $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
try {
|
||||
var_dump(new GMP("hello"));
|
||||
} catch (ValueError $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
object(GMP)#1 (1) {
|
||||
["num"]=>
|
||||
string(1) "0"
|
||||
}
|
||||
object(GMP)#1 (1) {
|
||||
["num"]=>
|
||||
string(1) "0"
|
||||
}
|
||||
object(GMP)#1 (1) {
|
||||
["num"]=>
|
||||
string(3) "123"
|
||||
}
|
||||
object(GMP)#1 (1) {
|
||||
["num"]=>
|
||||
string(3) "170"
|
||||
}
|
||||
object(GMP)#1 (1) {
|
||||
["num"]=>
|
||||
string(1) "6"
|
||||
}
|
||||
GMP::__construct(): Argument #2 ($base) must be between 2 and 62
|
||||
GMP::__construct(): Argument #1 ($num) is not an integer string
|
||||
GMP::__construct(): Argument #1 ($num) is not an integer string
|
Loading…
Reference in New Issue
Block a user