@@ -327,8 +327,18 @@ static zend_result binop_operator_helper(gmp_binary_op_t gmp_op, zval *return_va
327327
328328typedef void (* gmp_binary_ui_op_t )(mpz_ptr , mpz_srcptr , gmp_ulong );
329329
330+ static zend_result gmp_shift_operator_range_error (uint8_t opcode ) {
331+ zend_throw_error (
332+ zend_ce_value_error , "%s must be between 0 and %lu" ,
333+ opcode == ZEND_POW ? "Exponent" : "Shift" , ULONG_MAX
334+ );
335+ return FAILURE ;
336+ }
337+
330338static zend_result shift_operator_helper (gmp_binary_ui_op_t op , zval * return_value , zval * op1 , zval * op2 , uint8_t opcode ) {
331339 zend_long shift = 0 ;
340+ gmp_ulong shift_ui = 0 ;
341+ bool have_shift_ui = false;
332342
333343 if (UNEXPECTED (Z_TYPE_P (op2 ) != IS_LONG )) {
334344 if (UNEXPECTED (!IS_GMP (op2 ))) {
@@ -349,28 +359,33 @@ static zend_result shift_operator_helper(gmp_binary_ui_op_t op, zval *return_val
349359 goto typeof_op_failure ;
350360 }
351361 } else {
352- // TODO We shouldn't cast the GMP object to int here
353- shift = zval_get_long (op2 );
362+ mpz_ptr gmpnum_shift = GET_GMP_FROM_ZVAL (op2 );
363+ if (!mpz_fits_ulong_p (gmpnum_shift )) {
364+ return gmp_shift_operator_range_error (opcode );
365+ }
366+ shift_ui = (gmp_ulong ) mpz_get_ui (gmpnum_shift );
367+ have_shift_ui = true;
354368 }
355369 } else {
356370 shift = Z_LVAL_P (op2 );
357371 }
358372
359- if (shift < 0 || shift > ULONG_MAX ) {
360- zend_throw_error (
361- zend_ce_value_error , "%s must be between 0 and %lu" ,
362- opcode == ZEND_POW ? "Exponent" : "Shift" , ULONG_MAX
363- );
364- return FAILURE ;
365- } else {
373+ if (!have_shift_ui ) {
374+ if (shift < 0 || shift > ULONG_MAX ) {
375+ return gmp_shift_operator_range_error (opcode );
376+ }
377+ shift_ui = (gmp_ulong ) shift ;
378+ }
379+
380+ {
366381 mpz_ptr gmpnum_op , gmpnum_result ;
367382
368383 if (!gmp_zend_parse_arg_into_mpz_ex (op1 , & gmpnum_op , 1 , true)) {
369384 goto typeof_op_failure ;
370385 }
371386
372387 INIT_GMP_RETVAL (gmpnum_result );
373- op (gmpnum_result , gmpnum_op , ( gmp_ulong ) shift );
388+ op (gmpnum_result , gmpnum_op , shift_ui );
374389 return SUCCESS ;
375390 }
376391
0 commit comments