@@ -199,7 +199,7 @@ typedef void (*gmp_binary_ui_op_t)(mpz_ptr, mpz_srcptr, gmp_ulong);
199
199
typedef void (* gmp_binary_op2_t )(mpz_ptr , mpz_ptr , mpz_srcptr , mpz_srcptr );
200
200
typedef gmp_ulong (* gmp_binary_ui_op2_t )(mpz_ptr , mpz_ptr , mpz_srcptr , gmp_ulong );
201
201
202
- static inline void gmp_zval_binary_ui_op (zval * return_value , zval * a_arg , zval * b_arg , gmp_binary_op_t gmp_op , gmp_binary_ui_op_t gmp_ui_op , bool check_b_zero , bool is_operator );
202
+ static inline zend_result gmp_zval_binary_ui_op (zval * return_value , zval * a_arg , zval * b_arg , gmp_binary_op_t gmp_op , gmp_binary_ui_op_t gmp_ui_op , bool check_b_zero , bool is_operator );
203
203
static inline void gmp_zval_binary_ui_op2 (zval * return_value , zval * a_arg , zval * b_arg , gmp_binary_op2_t gmp_op , gmp_binary_ui_op2_t gmp_ui_op , int check_b_zero );
204
204
static inline void gmp_zval_unary_op (zval * return_value , zval * a_arg , gmp_unary_op_t gmp_op );
205
205
@@ -356,10 +356,7 @@ static void shift_operator_helper(gmp_binary_ui_op_t op, zval *return_value, zva
356
356
}
357
357
358
358
#define DO_BINARY_UI_OP_EX (op , uop , check_b_zero ) \
359
- gmp_zval_binary_ui_op( \
360
- result, op1, op2, op, uop, check_b_zero, /* is_operator */ true ); \
361
- if (UNEXPECTED(EG(exception))) { return FAILURE; } \
362
- return SUCCESS;
359
+ return gmp_zval_binary_ui_op(result, op1, op2, op, uop, check_b_zero, /* is_operator */ true );
363
360
364
361
#define DO_BINARY_UI_OP (op ) DO_BINARY_UI_OP_EX(op, op ## _ui, 0)
365
362
#define DO_BINARY_OP (op ) DO_BINARY_UI_OP_EX(op, NULL, 0)
@@ -437,7 +434,7 @@ static int gmp_compare(zval *op1, zval *op2) /* {{{ */
437
434
/* An error/exception occurs if one of the operands is not a numeric string
438
435
* or an object which is different from GMP */
439
436
if (EG (exception )) {
440
- return 1 ;
437
+ return ZEND_UNCOMPARABLE ;
441
438
}
442
439
/* result can only be a zend_long if gmp_cmp hasn't thrown an Error */
443
440
ZEND_ASSERT (Z_TYPE (result ) == IS_LONG );
@@ -619,7 +616,16 @@ static zend_result convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, ui
619
616
case IS_STRING : {
620
617
return convert_zstr_to_gmp (gmpnumber , Z_STR_P (val ), base , arg_pos );
621
618
}
622
- default : {
619
+ case IS_NULL :
620
+ /* For operator overloading just reject null */
621
+ if (arg_pos == 0 ) {
622
+ return FAILURE ;
623
+ }
624
+ ZEND_FALLTHROUGH ;
625
+ case IS_DOUBLE :
626
+ case IS_FALSE :
627
+ case IS_TRUE :
628
+ {
623
629
zend_long lval ;
624
630
if (!zend_parse_arg_long_slow (val , & lval , arg_pos )) {
625
631
if (arg_pos == 0 ) {
@@ -635,6 +641,12 @@ static zend_result convert_to_gmp(mpz_t gmpnumber, zval *val, zend_long base, ui
635
641
mpz_set_si (gmpnumber , lval );
636
642
return SUCCESS ;
637
643
}
644
+ default :
645
+ if (arg_pos != 0 ) {
646
+ zend_argument_type_error (arg_pos ,
647
+ "must be of type GMP|string|int, %s given" , zend_zval_type_name (val ));
648
+ }
649
+ return FAILURE ;
638
650
}
639
651
}
640
652
/* }}} */
@@ -702,18 +714,45 @@ static void gmp_cmp(zval *return_value, zval *a_arg, zval *b_arg, bool is_operat
702
714
/* {{{ gmp_zval_binary_ui_op
703
715
Execute GMP binary operation.
704
716
*/
705
- static inline void gmp_zval_binary_ui_op (zval * return_value , zval * a_arg , zval * b_arg , gmp_binary_op_t gmp_op , gmp_binary_ui_op_t gmp_ui_op , bool check_b_zero , bool is_operator )
717
+ static inline zend_result gmp_zval_binary_ui_op (zval * return_value , zval * a_arg , zval * b_arg , gmp_binary_op_t gmp_op , gmp_binary_ui_op_t gmp_ui_op , bool check_b_zero , bool is_operator )
706
718
{
707
719
mpz_ptr gmpnum_a , gmpnum_b , gmpnum_result ;
708
720
gmp_temp_t temp_a , temp_b ;
709
721
710
- FETCH_GMP_ZVAL (gmpnum_a , a_arg , temp_a , is_operator ? 0 : 1 );
722
+ /* Inline version of FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a, is_operator ? 0 : 1);
723
+ * because we cannot use RETURN_THROWS() here */
724
+ if (IS_GMP (a_arg )) {
725
+ gmpnum_a = GET_GMP_FROM_ZVAL (a_arg );
726
+ temp_a .is_used = 0 ;
727
+ } else {
728
+ mpz_init (temp_a .num );
729
+ if (convert_to_gmp (temp_a .num , a_arg , 0 , is_operator ? 0 : 1 ) == FAILURE ) {
730
+ mpz_clear (temp_a .num );
731
+ return FAILURE ;
732
+ }
733
+ temp_a .is_used = 1 ;
734
+ gmpnum_a = temp_a .num ;
735
+ }
711
736
712
737
if (gmp_ui_op && Z_TYPE_P (b_arg ) == IS_LONG && Z_LVAL_P (b_arg ) >= 0 ) {
713
738
gmpnum_b = NULL ;
714
739
temp_b .is_used = 0 ;
715
740
} else {
716
- FETCH_GMP_ZVAL_DEP (gmpnum_b , b_arg , temp_b , temp_a , is_operator ? 0 : 2 );
741
+ /* Inline version of FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a, is_operator ? 0 : 2);
742
+ * because we cannot use RETURN_THROWS() here */
743
+ if (IS_GMP (b_arg )) {
744
+ gmpnum_b = GET_GMP_FROM_ZVAL (b_arg );
745
+ temp_b .is_used = 0 ;
746
+ } else {
747
+ mpz_init (temp_b .num );
748
+ if (convert_to_gmp (temp_b .num , b_arg , 0 , is_operator ? 0 : 2 ) == FAILURE ) {
749
+ mpz_clear (temp_b .num );
750
+ FREE_GMP_TEMP (temp_a );
751
+ return FAILURE ;
752
+ }
753
+ temp_b .is_used = 1 ;
754
+ gmpnum_b = temp_b .num ;
755
+ }
717
756
}
718
757
719
758
if (check_b_zero ) {
@@ -732,7 +771,7 @@ static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval *
732
771
}
733
772
FREE_GMP_TEMP (temp_a );
734
773
FREE_GMP_TEMP (temp_b );
735
- RETURN_THROWS () ;
774
+ return FAILURE ;
736
775
}
737
776
}
738
777
@@ -746,6 +785,7 @@ static inline void gmp_zval_binary_ui_op(zval *return_value, zval *a_arg, zval *
746
785
747
786
FREE_GMP_TEMP (temp_a );
748
787
FREE_GMP_TEMP (temp_b );
788
+ return SUCCESS ;
749
789
}
750
790
/* }}} */
751
791
0 commit comments