diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 2e2d80f76f95..536fb1a7bf06 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -155,6 +155,15 @@ static zend_always_inline zend_result bcmath_check_scale(zend_long scale, uint32 return SUCCESS; } +static zend_result bcmath_check_precision(zend_long precision, uint32_t arg_num) +{ + if (ZEND_LONG_EXCEEDS_INT(precision)) { + zend_argument_value_error(arg_num, "must be between %d and %d", INT_MIN, INT_MAX); + return FAILURE; + } + return SUCCESS; +} + static void php_long2num(bc_num *num, zend_long lval) { *num = bc_long2num(lval); @@ -795,6 +804,10 @@ PHP_FUNCTION(bcround) Z_PARAM_ENUM(rounding_mode, rounding_mode_ce) ZEND_PARSE_PARAMETERS_END(); + if (bcmath_check_precision(precision, 2) == FAILURE) { + RETURN_THROWS(); + } + switch (rounding_mode) { case ZEND_ENUM_RoundingMode_HalfAwayFromZero: case ZEND_ENUM_RoundingMode_HalfTowardsZero: @@ -1794,6 +1807,10 @@ PHP_METHOD(BcMath_Number, round) Z_PARAM_ENUM(rounding_mode, rounding_mode_ce); ZEND_PARSE_PARAMETERS_END(); + if (bcmath_check_precision(precision, 1) == FAILURE) { + RETURN_THROWS(); + } + switch (rounding_mode) { case ZEND_ENUM_RoundingMode_HalfAwayFromZero: case ZEND_ENUM_RoundingMode_HalfTowardsZero: diff --git a/ext/bcmath/tests/bcround_precision_bounds.phpt b/ext/bcmath/tests/bcround_precision_bounds.phpt new file mode 100644 index 000000000000..9769760a79cd --- /dev/null +++ b/ext/bcmath/tests/bcround_precision_bounds.phpt @@ -0,0 +1,32 @@ +--TEST-- +bcround() and BcMath\Number::round() reject out-of-range $precision +--EXTENSIONS-- +bcmath +--FILE-- +getMessage() . \PHP_EOL; +} +try { + bcround('12345', -PHP_INT_MAX, RoundingMode::AwayFromZero); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + bcround('12345', PHP_INT_MIN, RoundingMode::AwayFromZero); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + (new BcMath\Number('1'))->round(PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +?> +--EXPECTF-- +bcround(): Argument #2 ($precision) must be between %i and %i +bcround(): Argument #2 ($precision) must be between %i and %i +bcround(): Argument #2 ($precision) must be between %i and %i +BcMath\Number::round(): Argument #1 ($precision) must be between %i and %i