Skip to content

Commit a4a985b

Browse files
committed
Added CHECK_SCALE_OVERFLOW and set init scale val
1 parent fad899e commit a4a985b

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

ext/bcmath/bcmath.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,7 @@ static int bcmath_number_compare(zval *op1, zval *op2);
803803
#else
804804
# define CHECK_RET_SCALE_OVERFLOW(scale, origin_scale) (scale > INT_MAX || scale < origin_scale)
805805
#endif
806+
#define CHECK_SCALE_OVERFLOW(scale) (scale > INT_MAX)
806807

807808
static zend_always_inline bcmath_number_obj_t *get_bcmath_number_from_obj(const zend_object *obj)
808809
{
@@ -1185,6 +1186,11 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva
11851186
goto fail;
11861187
}
11871188

1189+
if (UNEXPECTED(CHECK_SCALE_OVERFLOW(n1_full_scale) || CHECK_SCALE_OVERFLOW(n2_full_scale))) {
1190+
zend_value_error("Number has too large scale");
1191+
goto fail;
1192+
}
1193+
11881194
bc_num ret = NULL;
11891195
size_t scale;
11901196
switch (opcode) {
@@ -1265,8 +1271,15 @@ static int bcmath_number_compare(zval *op1, zval *op2)
12651271
goto fallback;
12661272
}
12671273

1268-
if (UNEXPECTED(bc_num_from_obj_or_str_or_long(&n1, NULL, obj1, str1, lval1) == FAILURE ||
1269-
bc_num_from_obj_or_str_or_long(&n2, NULL, obj2, str2, lval2) == FAILURE)) {
1274+
size_t n1_full_scale;
1275+
size_t n2_full_scale;
1276+
if (UNEXPECTED(bc_num_from_obj_or_str_or_long(&n1, &n1_full_scale, obj1, str1, lval1) == FAILURE ||
1277+
bc_num_from_obj_or_str_or_long(&n2, &n2_full_scale, obj2, str2, lval2) == FAILURE)) {
1278+
goto fallback;
1279+
}
1280+
1281+
if (UNEXPECTED(CHECK_SCALE_OVERFLOW(n1_full_scale) || CHECK_SCALE_OVERFLOW(n2_full_scale))) {
1282+
zend_value_error("Number has too large scale");
12701283
goto fallback;
12711284
}
12721285

@@ -1298,10 +1311,18 @@ static int bcmath_number_compare(zval *op1, zval *op2)
12981311
static zend_always_inline zend_result bc_num_from_obj_or_str_or_long_with_err(
12991312
bc_num *num, size_t *scale, zend_object *obj, zend_string *str, zend_long lval, uint32_t arg_num)
13001313
{
1301-
if (UNEXPECTED(bc_num_from_obj_or_str_or_long(num, scale, obj, str, lval) == FAILURE)) {
1314+
size_t full_scale = 0;
1315+
if (UNEXPECTED(bc_num_from_obj_or_str_or_long(num, &full_scale, obj, str, lval) == FAILURE)) {
13021316
zend_argument_value_error(arg_num, "is not well-formed");
13031317
return FAILURE;
13041318
}
1319+
if (UNEXPECTED(CHECK_SCALE_OVERFLOW(full_scale))) {
1320+
zend_argument_value_error(arg_num, "has too large scale");
1321+
return FAILURE;
1322+
}
1323+
if (scale != NULL) {
1324+
*scale = full_scale;
1325+
}
13051326
return SUCCESS;
13061327
}
13071328

@@ -1330,7 +1351,7 @@ PHP_METHOD(BcMath_Number, __construct)
13301351
}
13311352

13321353
bc_num num = NULL;
1333-
size_t scale;
1354+
size_t scale = 0;
13341355
if (bc_num_from_obj_or_str_or_long_with_err(&num, &scale, NULL, str, lval, 1) == FAILURE) {
13351356
bc_free_num(&num);
13361357
RETURN_THROWS();
@@ -1355,7 +1376,7 @@ static void bcmath_number_calc_method(INTERNAL_FUNCTION_PARAMETERS, uint8_t opco
13551376
ZEND_PARSE_PARAMETERS_END();
13561377

13571378
bc_num num = NULL;
1358-
size_t num_full_scale;
1379+
size_t num_full_scale = 0;
13591380
if (bc_num_from_obj_or_str_or_long_with_err(&num, &num_full_scale, num_obj, num_str, num_lval, 1) == FAILURE) {
13601381
goto fail;
13611382
}
@@ -1580,7 +1601,7 @@ PHP_METHOD(BcMath_Number, compare)
15801601
ZEND_PARSE_PARAMETERS_END();
15811602

15821603
bc_num num = NULL;
1583-
size_t num_full_scale;
1604+
size_t num_full_scale = 0;
15841605
if (bc_num_from_obj_or_str_or_long_with_err(&num, &num_full_scale, num_obj, num_str, num_lval, 1) == FAILURE) {
15851606
goto fail;
15861607
}
@@ -1714,8 +1735,8 @@ PHP_METHOD(BcMath_Number, __unserialize)
17141735
}
17151736

17161737
bc_num num = NULL;
1717-
size_t scale;
1718-
if (php_str2num_ex(&num, Z_STR_P(zv), &scale) == FAILURE) {
1738+
size_t scale = 0;
1739+
if (php_str2num_ex(&num, Z_STR_P(zv), &scale) == FAILURE || CHECK_SCALE_OVERFLOW(scale)) {
17191740
bc_free_num(&num);
17201741
goto fail;
17211742
}

0 commit comments

Comments
 (0)