From: Máté Kocsis Date: Mon, 25 May 2020 15:12:52 +0000 (+0200) Subject: Promote warning related to operator overloading in ext/gmp to an exception X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=43095a55e2b2d38f5ae89a3d5144798c278359ed;p=php Promote warning related to operator overloading in ext/gmp to an exception --- diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index a14c65f297..b6b3811a68 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -332,12 +332,16 @@ static zend_object *gmp_clone_obj(zend_object *obj) /* {{{ */ } /* }}} */ -static void shift_operator_helper(gmp_binary_ui_op_t op, zval *return_value, zval *op1, zval *op2) { +static void shift_operator_helper(gmp_binary_ui_op_t op, zval *return_value, zval *op1, zval *op2, zend_uchar opcode) { zend_long shift = zval_get_long(op2); if (shift < 0) { - php_error_docref(NULL, E_WARNING, "Shift cannot be negative"); - RETVAL_FALSE; + zend_throw_error( + zend_ce_value_error, "%s must be greater than or equal to 0", + opcode == ZEND_POW ? "Exponent" : "Shift" + ); + ZVAL_UNDEF(return_value); + return; } else { mpz_ptr gmpnum_op, gmpnum_result; gmp_temp_t temp; @@ -372,17 +376,17 @@ static int gmp_do_operation_ex(zend_uchar opcode, zval *result, zval *op1, zval case ZEND_MUL: DO_BINARY_UI_OP(mpz_mul); case ZEND_POW: - shift_operator_helper(mpz_pow_ui, result, op1, op2); + shift_operator_helper(mpz_pow_ui, result, op1, op2, opcode); return SUCCESS; case ZEND_DIV: DO_BINARY_UI_OP_EX(mpz_tdiv_q, gmp_mpz_tdiv_q_ui, 1); case ZEND_MOD: DO_BINARY_UI_OP_EX(mpz_mod, gmp_mpz_mod_ui, 1); case ZEND_SL: - shift_operator_helper(mpz_mul_2exp, result, op1, op2); + shift_operator_helper(mpz_mul_2exp, result, op1, op2, opcode); return SUCCESS; case ZEND_SR: - shift_operator_helper(mpz_fdiv_q_2exp, result, op1, op2); + shift_operator_helper(mpz_fdiv_q_2exp, result, op1, op2, opcode); return SUCCESS; case ZEND_BW_OR: DO_BINARY_OP(mpz_ior); @@ -520,7 +524,7 @@ static ZEND_GINIT_FUNCTION(gmp) ZEND_MINIT_FUNCTION(gmp) { zend_class_entry tmp_ce; - INIT_CLASS_ENTRY(tmp_ce, "GMP", NULL); + INIT_CLASS_ENTRY(tmp_ce, "GMP", class_GMP_methods); gmp_ce = zend_register_internal_class(&tmp_ce); gmp_ce->create_object = gmp_create_object; gmp_ce->serialize = gmp_serialize; @@ -1261,8 +1265,8 @@ ZEND_FUNCTION(gmp_pow) } if (exp < 0) { - php_error_docref(NULL, E_WARNING, "Negative exponent not supported"); - RETURN_FALSE; + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); } if (Z_TYPE_P(base_arg) == IS_LONG && Z_LVAL_P(base_arg) >= 0) { diff --git a/ext/gmp/gmp.stub.php b/ext/gmp/gmp.stub.php index a95616aa4e..bfa4ba93ee 100644 --- a/ext/gmp/gmp.stub.php +++ b/ext/gmp/gmp.stub.php @@ -2,6 +2,10 @@ /** @generate-function-entries */ +class GMP +{ +} + /** @param int|bool|string $number */ function gmp_init($number, int $base = 0): GMP|false {} diff --git a/ext/gmp/gmp_arginfo.h b/ext/gmp/gmp_arginfo.h index b0309824d4..4cb06da28e 100644 --- a/ext/gmp/gmp_arginfo.h +++ b/ext/gmp/gmp_arginfo.h @@ -289,3 +289,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(gmp_binomial, arginfo_gmp_binomial) ZEND_FE_END }; + + +static const zend_function_entry class_GMP_methods[] = { + ZEND_FE_END +}; diff --git a/ext/gmp/tests/gmp_pow.phpt b/ext/gmp/tests/gmp_pow.phpt index 449f668667..523150765d 100644 --- a/ext/gmp/tests/gmp_pow.phpt +++ b/ext/gmp/tests/gmp_pow.phpt @@ -10,11 +10,19 @@ 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))); -var_dump(gmp_strval(gmp_pow("2",-1))); +try { + gmp_pow("2", -1); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} var_dump(gmp_strval(gmp_pow("-2",10))); var_dump(gmp_strval(gmp_pow(20,10))); var_dump(gmp_strval(gmp_pow(50,10))); -var_dump(gmp_strval(gmp_pow(50,-5))); +try { + gmp_pow(50,-5); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} $n = gmp_init("20"); var_dump(gmp_strval(gmp_pow($n,10))); @@ -36,15 +44,11 @@ string(4) "1024" string(5) "-2048" string(4) "1024" string(1) "1" - -Warning: gmp_pow(): Negative exponent not supported in %s on line %d -string(1) "0" +gmp_pow(): Argument #2 ($exp) must be greater than or equal to 0 string(4) "1024" string(14) "10240000000000" string(17) "97656250000000000" - -Warning: gmp_pow(): Negative exponent not supported in %s on line %d -string(1) "0" +gmp_pow(): Argument #2 ($exp) must be greater than or equal to 0 string(14) "10240000000000" string(14) "10240000000000" gmp_pow(): Argument #2 ($exp) must be of type int, array given diff --git a/ext/gmp/tests/gmp_pow2.phpt b/ext/gmp/tests/gmp_pow2.phpt new file mode 100644 index 0000000000..e1007e8d4d --- /dev/null +++ b/ext/gmp/tests/gmp_pow2.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test pow() with gmp object +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} + +try { + $n ** -10; +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECTF-- +object(GMP)#%d (1) { + ["num"]=> + string(4) "1024" +} +object(GMP)#%d (1) { + ["num"]=> + string(4) "1024" +} +Exponent must be greater than or equal to 0 +Exponent must be greater than or equal to 0 diff --git a/ext/gmp/tests/overloading.phpt b/ext/gmp/tests/overloading.phpt index 3520f58bdc..c38b1eaf82 100644 --- a/ext/gmp/tests/overloading.phpt +++ b/ext/gmp/tests/overloading.phpt @@ -53,8 +53,17 @@ var_dump(42 << $b); var_dump($a >> 2); var_dump(-$a >> 2); -var_dump($a << -1); -var_dump($a >> -1); +try { + $a << -1; +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + $a >> -1; +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} var_dump(~$a); var_dump(-$a); @@ -237,12 +246,8 @@ object(GMP)#%d (1) { ["num"]=> string(3) "-11" } - -Warning: main(): Shift cannot be negative in %s on line %d -bool(false) - -Warning: main(): Shift cannot be negative in %s on line %d -bool(false) +Shift must be greater than or equal to 0 +Shift must be greater than or equal to 0 object(GMP)#%d (1) { ["num"]=> string(3) "-43"