Skip to content

Commit a550e14

Browse files
committed
Fixed to issue an error if the result scale exceeds INT_MAX.
1 parent 8162b94 commit a550e14

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

ext/bcmath/bcmath.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -978,24 +978,33 @@ static zend_always_inline void bcmath_number_sub_internal(
978978
bc_rm_trailing_zeros(*ret);
979979
}
980980

981-
static zend_always_inline void bcmath_number_mul_internal(
981+
static zend_always_inline zend_result bcmath_number_mul_internal(
982982
bc_num n1, bc_num n2, bc_num *ret,
983983
size_t n1_full_scale, size_t n2_full_scale, size_t *scale, bool auto_scale
984984
) {
985985
if (auto_scale) {
986-
*scale = MIN(n1_full_scale + n2_full_scale, INT_MAX);
986+
*scale = n1_full_scale + n2_full_scale;
987+
if (UNEXPECTED(*scale > INT_MAX)) {
988+
zend_value_error("scale of the result is too large");
989+
return FAILURE;
990+
}
987991
}
988992
*ret = bc_multiply(n1, n2, *scale);
989993
(*ret)->n_scale = MIN(*scale, (*ret)->n_scale);
990994
bc_rm_trailing_zeros(*ret);
995+
return SUCCESS;
991996
}
992997

993998
static zend_always_inline zend_result bcmath_number_div_internal(
994999
bc_num n1, bc_num n2, bc_num *ret,
9951000
size_t n1_full_scale, size_t *scale, bool auto_scale
9961001
) {
9971002
if (auto_scale) {
998-
*scale = MIN(n1_full_scale + BC_MATH_NUMBER_EXPAND_SCALE, INT_MAX);
1003+
*scale = n1_full_scale + BC_MATH_NUMBER_EXPAND_SCALE;
1004+
if (UNEXPECTED(*scale > INT_MAX)) {
1005+
zend_value_error("scale of the result is too large");
1006+
return FAILURE;
1007+
}
9991008
}
10001009
if (!bc_divide(n1, n2, ret, *scale)) {
10011010
zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Division by zero");
@@ -1044,10 +1053,15 @@ static zend_always_inline zend_result bcmath_number_pow_internal(
10441053
if (exponent > 0) {
10451054
*scale = n1_full_scale * exponent;
10461055
if (UNEXPECTED(*scale > INT_MAX || *scale < n1_full_scale)) {
1047-
*scale = INT_MAX;
1056+
zend_value_error("scale of the result is too large");
1057+
return FAILURE;
10481058
}
10491059
} else if (exponent < 0) {
1050-
*scale = MIN(n1_full_scale + BC_MATH_NUMBER_EXPAND_SCALE, INT_MAX);
1060+
*scale = n1_full_scale + BC_MATH_NUMBER_EXPAND_SCALE;
1061+
if (UNEXPECTED(*scale > INT_MAX)) {
1062+
zend_value_error("scale of the result is too large");
1063+
return FAILURE;
1064+
}
10511065
scale_expand = true;
10521066
} else {
10531067
*scale = 0;
@@ -1201,7 +1215,9 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva
12011215
bcmath_number_sub_internal(n1, n2, &ret, n1_full_scale, n2_full_scale, &scale, true);
12021216
break;
12031217
case ZEND_MUL:
1204-
bcmath_number_mul_internal(n1, n2, &ret, n1_full_scale, n2_full_scale, &scale, true);
1218+
if (UNEXPECTED(bcmath_number_mul_internal(n1, n2, &ret, n1_full_scale, n2_full_scale, &scale, true) == FAILURE)) {
1219+
goto fail;
1220+
}
12051221
break;
12061222
case ZEND_DIV:
12071223
if (UNEXPECTED(bcmath_number_div_internal(n1, n2, &ret, n1_full_scale, &scale, true) == FAILURE)) {
@@ -1396,7 +1412,9 @@ static void bcmath_number_calc_method(INTERNAL_FUNCTION_PARAMETERS, uint8_t opco
13961412
bcmath_number_sub_internal(intern->num, num, &ret, intern->scale, num_full_scale, &scale, scale_is_null);
13971413
break;
13981414
case ZEND_MUL:
1399-
bcmath_number_mul_internal(intern->num, num, &ret, intern->scale, num_full_scale, &scale, scale_is_null);
1415+
if (UNEXPECTED(bcmath_number_mul_internal(intern->num, num, &ret, intern->scale, num_full_scale, &scale, scale_is_null) == FAILURE)) {
1416+
goto fail;
1417+
}
14001418
break;
14011419
case ZEND_DIV:
14021420
if (UNEXPECTED(bcmath_number_div_internal(intern->num, num, &ret, intern->scale, &scale, scale_is_null) == FAILURE)) {
@@ -1560,7 +1578,11 @@ PHP_METHOD(BcMath_Number, sqrt)
15601578

15611579
size_t scale;
15621580
if (scale_is_null) {
1563-
scale = MIN(intern->scale + BC_MATH_NUMBER_EXPAND_SCALE, INT_MAX);
1581+
scale = intern->scale + BC_MATH_NUMBER_EXPAND_SCALE;
1582+
if (UNEXPECTED(scale > INT_MAX)) {
1583+
zend_value_error("scale of the result is too large");
1584+
RETURN_THROWS();
1585+
}
15641586
} else {
15651587
scale = scale_lval;
15661588
}

0 commit comments

Comments
 (0)