diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 752d18ec5643..b50cfe2efbb8 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -339,7 +339,23 @@ 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, uint8_t opcode) { - zend_long shift = zval_get_long(op2); + bool failed = true; + zend_long shift = zval_try_get_long(op2, &failed); + if (failed) { + const char *operator_sigil; + if (opcode == ZEND_POW) { + operator_sigil = "**"; + } else if (opcode == ZEND_SL) { + operator_sigil = "<<"; + } else { + ZEND_ASSERT(opcode == ZEND_SR); + operator_sigil = ">>"; + } + + zend_type_error("Unsupported operand types: GMP %s %s", operator_sigil, zend_zval_value_name(op2)); + ZVAL_UNDEF(return_value); + return; + } if (shift < 0) { zend_throw_error( diff --git a/ext/gmp/tests/gmp_pow_error.phpt b/ext/gmp/tests/gmp_pow_error.phpt new file mode 100644 index 000000000000..5ade76878fc6 --- /dev/null +++ b/ext/gmp/tests/gmp_pow_error.phpt @@ -0,0 +1,41 @@ +--TEST-- +Native exponential with invalid exponent +--EXTENSIONS-- +gmp +--FILE-- +getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n ** new stdClass()); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n ** STDERR); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n ** []); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} + + +echo "Done\n"; +?> +--EXPECT-- +TypeError: Unsupported operand types: GMP ** string +TypeError: Unsupported operand types: GMP ** stdClass +TypeError: Unsupported operand types: GMP ** resource +TypeError: Unsupported operand types: GMP ** array +Done diff --git a/ext/gmp/tests/gmp_shift_left_error.phpt b/ext/gmp/tests/gmp_shift_left_error.phpt new file mode 100644 index 000000000000..283295fd58f8 --- /dev/null +++ b/ext/gmp/tests/gmp_shift_left_error.phpt @@ -0,0 +1,41 @@ +--TEST-- +Native shift left with invalid op2 +--EXTENSIONS-- +gmp +--FILE-- +getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n << new stdClass()); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n << STDERR); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n << []); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} + + +echo "Done\n"; +?> +--EXPECT-- +TypeError: Unsupported operand types: GMP << string +TypeError: Unsupported operand types: GMP << stdClass +TypeError: Unsupported operand types: GMP << resource +TypeError: Unsupported operand types: GMP << array +Done diff --git a/ext/gmp/tests/gmp_shift_right_error.phpt b/ext/gmp/tests/gmp_shift_right_error.phpt new file mode 100644 index 000000000000..26c6adb125a5 --- /dev/null +++ b/ext/gmp/tests/gmp_shift_right_error.phpt @@ -0,0 +1,41 @@ +--TEST-- +Native shift right with invalid op2 +--EXTENSIONS-- +gmp +--FILE-- +> "nonsense"); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n >> new stdClass()); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n >> STDERR); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} +try { + $n = gmp_init("6"); + var_dump($n >> []); +} catch (\Throwable $e) { + echo $e::class, ': ', $e->getMessage(), \PHP_EOL; +} + + +echo "Done\n"; +?> +--EXPECT-- +TypeError: Unsupported operand types: GMP >> string +TypeError: Unsupported operand types: GMP >> stdClass +TypeError: Unsupported operand types: GMP >> resource +TypeError: Unsupported operand types: GMP >> array +Done