@@ -848,7 +848,7 @@ static zend_object *bcmath_number_clone(zend_object *object)
848
848
return & clone -> std ;
849
849
}
850
850
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 )
852
852
{
853
853
switch (Z_TYPE_P (zv )) {
854
854
case IS_LONG :
@@ -860,7 +860,6 @@ static inline zend_result bc_num_from_zval(const zval *zv, bc_num *num, size_t *
860
860
861
861
case IS_STRING :
862
862
if (php_str2num_ex (num , Z_STR_P (zv ), full_scale ) == FAILURE ) {
863
- zend_argument_value_error (arg_num , "is not well-formed" );
864
863
bc_free_num (num );
865
864
return FAILURE ;
866
865
}
@@ -878,13 +877,21 @@ static inline zend_result bc_num_from_zval(const zval *zv, bc_num *num, size_t *
878
877
ZEND_FALLTHROUGH ;
879
878
880
879
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 ));
882
880
return FAILURE ;
883
881
}
884
882
885
883
return SUCCESS ;
886
884
}
887
885
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
+
888
895
static HashTable * bcmath_number_get_properties_for (zend_object * obj , zend_prop_purpose purpose )
889
896
{
890
897
switch (purpose ) {
@@ -1101,7 +1108,7 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva
1101
1108
bc_num n1 = NULL , n2 = NULL ;
1102
1109
size_t n1_full_scale , n2_full_scale ;
1103
1110
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 )) {
1105
1112
goto fail ;
1106
1113
}
1107
1114
@@ -1170,14 +1177,23 @@ static zend_result bcmath_number_do_operation(uint8_t opcode, zval *ret_val, zva
1170
1177
return FAILURE ;
1171
1178
}
1172
1179
1173
- static int bcmath_number_compare (zval * z1 , zval * z2 )
1180
+ static int bcmath_number_compare (zval * op1 , zval * op2 )
1174
1181
{
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
+ }
1176
1186
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
+ }
1179
1195
1180
- return bc_compare ( n1 -> num , n2 -> num ) ;
1196
+ return ret ;
1181
1197
}
1182
1198
1183
1199
PHP_METHOD (BcMath_Number , __construct )
@@ -1192,7 +1208,8 @@ PHP_METHOD(BcMath_Number, __construct)
1192
1208
1193
1209
bc_num num = NULL ;
1194
1210
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 );
1196
1213
RETURN_THROWS ();
1197
1214
}
1198
1215
@@ -1223,7 +1240,8 @@ static inline zend_result bc_check_scale(zend_long scale, bool scale_is_null, ui
1223
1240
bc_num num = NULL; \
1224
1241
size_t num_full_scale; \
1225
1242
\
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); \
1227
1245
RETURN_THROWS(); \
1228
1246
} \
1229
1247
\
@@ -1317,24 +1335,24 @@ PHP_METHOD(BcMath_Number, powmod)
1317
1335
Z_PARAM_LONG_OR_NULL (arg_scale , scale_is_null );
1318
1336
ZEND_PARSE_PARAMETERS_END ();
1319
1337
1320
- bcmath_number_obj_t * intern = get_bcmath_number_from_zval (ZEND_THIS );
1321
-
1322
1338
bc_num exponent_num = NULL ;
1323
1339
bc_num modulus_num = NULL ;
1324
1340
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 );
1326
1343
goto cleanup ;
1327
1344
}
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 );
1329
1347
goto cleanup ;
1330
1348
}
1331
1349
if (bc_check_scale (arg_scale , scale_is_null , 3 ) == FAILURE ) {
1332
1350
goto cleanup ;
1333
1351
}
1334
1352
1335
- size_t scale = 0 ;
1336
-
1353
+ bcmath_number_obj_t * intern = get_bcmath_number_from_zval (ZEND_THIS );
1337
1354
bc_num ret = NULL ;
1355
+ size_t scale = scale_is_null ? 0 : arg_scale ;
1338
1356
raise_mod_status status = bc_raisemod (intern -> num , exponent_num , modulus_num , & ret , scale );
1339
1357
switch (status ) {
1340
1358
case BASE_HAS_FRACTIONAL :
@@ -1424,7 +1442,8 @@ PHP_METHOD(BcMath_Number, comp)
1424
1442
ZEND_PARSE_PARAMETERS_END ();
1425
1443
1426
1444
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 );
1428
1447
RETURN_THROWS ();
1429
1448
}
1430
1449
0 commit comments