Skip to content

Commit 5f12fff

Browse files
committed
wip
1 parent 6e76f60 commit 5f12fff

File tree

1 file changed

+37
-18
lines changed

1 file changed

+37
-18
lines changed

ext/bcmath/bcmath.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ static zend_object *bcmath_number_clone(zend_object *object)
848848
return &clone->std;
849849
}
850850

851-
static inline zend_result bc_num_from_zval(const zval *zv, bc_num *num, size_t *full_scale, uint32_t arg_num)
851+
static inline zend_result bc_num_from_zval(const zval *zv, bc_num *num, size_t *full_scale)
852852
{
853853
switch (Z_TYPE_P(zv)) {
854854
case IS_LONG:
@@ -860,7 +860,6 @@ static inline zend_result bc_num_from_zval(const zval *zv, bc_num *num, size_t *
860860

861861
case IS_STRING:
862862
if (php_str2num_ex(num, Z_STR_P(zv), full_scale) == FAILURE) {
863-
zend_argument_value_error(arg_num, "is not well-formed");
864863
bc_free_num(num);
865864
return FAILURE;
866865
}
@@ -878,13 +877,21 @@ static inline zend_result bc_num_from_zval(const zval *zv, bc_num *num, size_t *
878877
ZEND_FALLTHROUGH;
879878

880879
default:
881-
zend_argument_type_error(arg_num, "must be of type int, string, or %s, %s given", ZSTR_VAL(Z_OBJ_P(zv)->ce->name), zend_zval_value_name(zv));
882880
return FAILURE;
883881
}
884882

885883
return SUCCESS;
886884
}
887885

886+
static inline void bc_num_from_zval_error_message(const zval *zv, uint32_t arg_num)
887+
{
888+
if (Z_TYPE_P(zv) == IS_STRING) {
889+
zend_argument_value_error(arg_num, "is not well-formed");
890+
} else {
891+
zend_argument_type_error(arg_num, "must be of type int, string, or %s, %s given", ZSTR_VAL(bcmath_number_ce->name), zend_zval_value_name(zv));
892+
}
893+
}
894+
888895
static HashTable *bcmath_number_get_properties_for(zend_object *obj, zend_prop_purpose purpose)
889896
{
890897
switch (purpose) {
@@ -1101,7 +1108,7 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva
11011108
bc_num n1 = NULL, n2 = NULL;
11021109
size_t n1_full_scale, n2_full_scale;
11031110

1104-
if (UNEXPECTED(bc_num_from_zval(op1, &n1, &n1_full_scale, 0) == FAILURE || bc_num_from_zval(op2, &n2, &n2_full_scale, 0) == FAILURE)) {
1111+
if (UNEXPECTED(bc_num_from_zval(op1, &n1, &n1_full_scale) == FAILURE || bc_num_from_zval(op2, &n2, &n2_full_scale) == FAILURE)) {
11051112
goto fail;
11061113
}
11071114

@@ -1170,14 +1177,23 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva
11701177
return FAILURE;
11711178
}
11721179

1173-
static int bcmath_number_compare(zval *z1, zval *z2)
1180+
static int bcmath_number_compare(zval *op1, zval *op2)
11741181
{
1175-
ZEND_COMPARE_OBJECTS_FALLBACK(z1, z2);
1182+
bc_num n1 = NULL, n2 = NULL;
1183+
if (UNEXPECTED(bc_num_from_zval(op1, &n1, NULL) == FAILURE || bc_num_from_zval(op2, &n2, NULL) == FAILURE)) {
1184+
return zend_std_compare_objects(op1, op2);
1185+
}
11761186

1177-
bcmath_number_obj_t *n1 = get_bcmath_number_from_zval(z1);
1178-
bcmath_number_obj_t *n2 = get_bcmath_number_from_zval(z2);
1187+
int ret = bc_compare(n1, n2);
1188+
1189+
if (n1 && Z_TYPE_P(op1) != IS_OBJECT) {
1190+
bc_free_num(&n1);
1191+
}
1192+
if (n2 && Z_TYPE_P(op2) != IS_OBJECT) {
1193+
bc_free_num(&n2);
1194+
}
11791195

1180-
return bc_compare(n1->num, n2->num);
1196+
return ret;
11811197
}
11821198

11831199
PHP_METHOD(BcMath_Number, __construct)
@@ -1192,7 +1208,8 @@ PHP_METHOD(BcMath_Number, __construct)
11921208

11931209
bc_num num = NULL;
11941210
size_t scale;
1195-
if (bc_num_from_zval(zv, &num, &scale, 1) == FAILURE) {
1211+
if (bc_num_from_zval(zv, &num, &scale) == FAILURE) {
1212+
bc_num_from_zval_error_message(zv, 1);
11961213
RETURN_THROWS();
11971214
}
11981215

@@ -1223,7 +1240,8 @@ static inline zend_result bc_check_scale(zend_long scale, bool scale_is_null, ui
12231240
bc_num num = NULL; \
12241241
size_t num_full_scale; \
12251242
\
1226-
if (bc_num_from_zval(zv, &num, &num_full_scale, 1) == FAILURE) { \
1243+
if (bc_num_from_zval(zv, &num, &num_full_scale) == FAILURE) { \
1244+
bc_num_from_zval_error_message(zv, 1); \
12271245
RETURN_THROWS(); \
12281246
} \
12291247
\
@@ -1317,24 +1335,24 @@ PHP_METHOD(BcMath_Number, powmod)
13171335
Z_PARAM_LONG_OR_NULL(arg_scale, scale_is_null);
13181336
ZEND_PARSE_PARAMETERS_END();
13191337

1320-
bcmath_number_obj_t *intern = get_bcmath_number_from_zval(ZEND_THIS);
1321-
13221338
bc_num exponent_num = NULL;
13231339
bc_num modulus_num = NULL;
13241340

1325-
if (bc_num_from_zval(exponent, &exponent_num, NULL, 1) == FAILURE) {
1341+
if (bc_num_from_zval(exponent, &exponent_num, NULL) == FAILURE) {
1342+
bc_num_from_zval_error_message(exponent, 1);
13261343
goto cleanup;
13271344
}
1328-
if (bc_num_from_zval(modulus, &modulus_num, NULL, 2) == FAILURE) {
1345+
if (bc_num_from_zval(modulus, &modulus_num, NULL) == FAILURE) {
1346+
bc_num_from_zval_error_message(modulus, 2);
13291347
goto cleanup;
13301348
}
13311349
if (bc_check_scale(arg_scale, scale_is_null, 3) == FAILURE) {
13321350
goto cleanup;
13331351
}
13341352

1335-
size_t scale = 0;
1336-
1353+
bcmath_number_obj_t *intern = get_bcmath_number_from_zval(ZEND_THIS);
13371354
bc_num ret = NULL;
1355+
size_t scale = scale_is_null ? 0 : arg_scale;
13381356
raise_mod_status status = bc_raisemod(intern->num, exponent_num, modulus_num, &ret, scale);
13391357
switch (status) {
13401358
case BASE_HAS_FRACTIONAL:
@@ -1424,7 +1442,8 @@ PHP_METHOD(BcMath_Number, comp)
14241442
ZEND_PARSE_PARAMETERS_END();
14251443

14261444
bc_num num = NULL;
1427-
if (bc_num_from_zval(zv, &num, NULL, 1) == FAILURE) {
1445+
if (bc_num_from_zval(zv, &num, NULL) == FAILURE) {
1446+
bc_num_from_zval_error_message(zv, 1);
14281447
RETURN_THROWS();
14291448
}
14301449

0 commit comments

Comments
 (0)