From 03775973135e575f3524f484fff046a29e064b5f Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Wed, 4 Sep 2024 15:52:07 +0900 Subject: [PATCH 1/3] Added CHECK_SCALE_OVERFLOW and set init scale val --- ext/bcmath/bcmath.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index b7fef270c93d..f482cf0e080a 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -802,6 +802,7 @@ static int bcmath_number_compare(zval *op1, zval *op2); #else # define CHECK_RET_SCALE_OVERFLOW(scale, origin_scale) (scale > INT_MAX || scale < origin_scale) #endif +#define CHECK_SCALE_OVERFLOW(scale) (scale > INT_MAX) static zend_always_inline bcmath_number_obj_t *get_bcmath_number_from_obj(const zend_object *obj) { @@ -1184,6 +1185,11 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva goto fail; } + if (UNEXPECTED(CHECK_SCALE_OVERFLOW(n1_full_scale) || CHECK_SCALE_OVERFLOW(n2_full_scale))) { + zend_value_error("Number has too large scale"); + goto fail; + } + bc_num ret = NULL; size_t scale; switch (opcode) { @@ -1264,8 +1270,15 @@ static int bcmath_number_compare(zval *op1, zval *op2) goto fallback; } - if (UNEXPECTED(bc_num_from_obj_or_str_or_long(&n1, NULL, obj1, str1, lval1) == FAILURE || - bc_num_from_obj_or_str_or_long(&n2, NULL, obj2, str2, lval2) == FAILURE)) { + size_t n1_full_scale; + size_t n2_full_scale; + if (UNEXPECTED(bc_num_from_obj_or_str_or_long(&n1, &n1_full_scale, obj1, str1, lval1) == FAILURE || + bc_num_from_obj_or_str_or_long(&n2, &n2_full_scale, obj2, str2, lval2) == FAILURE)) { + goto fallback; + } + + if (UNEXPECTED(CHECK_SCALE_OVERFLOW(n1_full_scale) || CHECK_SCALE_OVERFLOW(n2_full_scale))) { + zend_value_error("Number has too large scale"); goto fallback; } @@ -1297,10 +1310,18 @@ static int bcmath_number_compare(zval *op1, zval *op2) static zend_always_inline zend_result bc_num_from_obj_or_str_or_long_with_err( bc_num *num, size_t *scale, zend_object *obj, zend_string *str, zend_long lval, uint32_t arg_num) { - if (UNEXPECTED(bc_num_from_obj_or_str_or_long(num, scale, obj, str, lval) == FAILURE)) { + size_t full_scale = 0; + if (UNEXPECTED(bc_num_from_obj_or_str_or_long(num, &full_scale, obj, str, lval) == FAILURE)) { zend_argument_value_error(arg_num, "is not well-formed"); return FAILURE; } + if (UNEXPECTED(CHECK_SCALE_OVERFLOW(full_scale))) { + zend_argument_value_error(arg_num, "has too large scale"); + return FAILURE; + } + if (scale != NULL) { + *scale = full_scale; + } return SUCCESS; } @@ -1320,7 +1341,7 @@ PHP_METHOD(BcMath_Number, __construct) } bc_num num = NULL; - size_t scale; + size_t scale = 0; if (bc_num_from_obj_or_str_or_long_with_err(&num, &scale, NULL, str, lval, 1) == FAILURE) { bc_free_num(&num); RETURN_THROWS(); @@ -1345,7 +1366,7 @@ static void bcmath_number_calc_method(INTERNAL_FUNCTION_PARAMETERS, uint8_t opco ZEND_PARSE_PARAMETERS_END(); bc_num num = NULL; - size_t num_full_scale; + size_t num_full_scale = 0; if (bc_num_from_obj_or_str_or_long_with_err(&num, &num_full_scale, num_obj, num_str, num_lval, 1) == FAILURE) { goto fail; } @@ -1570,7 +1591,7 @@ PHP_METHOD(BcMath_Number, compare) ZEND_PARSE_PARAMETERS_END(); bc_num num = NULL; - size_t num_full_scale; + size_t num_full_scale = 0; if (bc_num_from_obj_or_str_or_long_with_err(&num, &num_full_scale, num_obj, num_str, num_lval, 1) == FAILURE) { goto fail; } @@ -1704,8 +1725,8 @@ PHP_METHOD(BcMath_Number, __unserialize) } bc_num num = NULL; - size_t scale; - if (php_str2num_ex(&num, Z_STR_P(zv), &scale) == FAILURE) { + size_t scale = 0; + if (php_str2num_ex(&num, Z_STR_P(zv), &scale) == FAILURE || CHECK_SCALE_OVERFLOW(scale)) { bc_free_num(&num); goto fail; } From c067f4b1a2934e2d2ab321a9ea66a74675f644b4 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Thu, 19 Sep 2024 22:06:12 +0900 Subject: [PATCH 2/3] Address comment --- ext/bcmath/bcmath.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index f482cf0e080a..924e63f50f88 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -1186,7 +1186,7 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva } if (UNEXPECTED(CHECK_SCALE_OVERFLOW(n1_full_scale) || CHECK_SCALE_OVERFLOW(n2_full_scale))) { - zend_value_error("Number has too large scale"); + zend_value_error("scale must be between 0 and %d", INT_MAX); goto fail; } @@ -1278,7 +1278,7 @@ static int bcmath_number_compare(zval *op1, zval *op2) } if (UNEXPECTED(CHECK_SCALE_OVERFLOW(n1_full_scale) || CHECK_SCALE_OVERFLOW(n2_full_scale))) { - zend_value_error("Number has too large scale"); + zend_value_error("scale must be between 0 and %d", INT_MAX); goto fallback; } @@ -1316,7 +1316,7 @@ static zend_always_inline zend_result bc_num_from_obj_or_str_or_long_with_err( return FAILURE; } if (UNEXPECTED(CHECK_SCALE_OVERFLOW(full_scale))) { - zend_argument_value_error(arg_num, "has too large scale"); + zend_argument_value_error(arg_num, "must be between 0 and %d", INT_MAX); return FAILURE; } if (scale != NULL) { From ea6a41a1d2a7074da0eb914932753fb6634d8d92 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Sun, 22 Sep 2024 06:58:28 +0900 Subject: [PATCH 3/3] [ci skip] NEWS --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 976713cefdb6..c79113d63d5e 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,7 @@ PHP NEWS - BcMath: . bcpow() performance improvement. (Jorg Sowa) + . ext/bcmath: Check for scale overflow. (SakiTakamachi) - Debugging: . Fixed bug GH-15923 (GDB: Python Exception :