32
32
ZEND_DECLARE_MODULE_GLOBALS (bcmath )
33
33
static PHP_GINIT_FUNCTION (bcmath );
34
34
static PHP_GSHUTDOWN_FUNCTION (bcmath );
35
+ static PHP_MINIT_FUNCTION (bcmath );
36
+ static PHP_MSHUTDOWN_FUNCTION (bcmath );
37
+ static PHP_MINFO_FUNCTION (bcmath );
35
38
36
39
zend_module_entry bcmath_module_entry = {
37
40
STANDARD_MODULE_HEADER ,
@@ -341,15 +344,13 @@ PHP_FUNCTION(bcdiv)
341
344
goto cleanup ;
342
345
}
343
346
344
- switch (bc_divide (first , second , & result , scale )) {
345
- case 0 : /* OK */
346
- RETVAL_STR (bc_num2str_ex (result , scale ));
347
- break ;
348
- case -1 : /* division by zero */
349
- zend_throw_exception_ex (zend_ce_division_by_zero_error , 0 , "Division by zero" );
350
- break ;
347
+ if (!bc_divide (first , second , & result , scale )) {
348
+ zend_throw_exception_ex (zend_ce_division_by_zero_error , 0 , "Division by zero" );
349
+ goto cleanup ;
351
350
}
352
351
352
+ RETVAL_STR (bc_num2str_ex (result , scale ));
353
+
353
354
cleanup : {
354
355
bc_free_num (& first );
355
356
bc_free_num (& second );
@@ -397,15 +398,13 @@ PHP_FUNCTION(bcmod)
397
398
goto cleanup ;
398
399
}
399
400
400
- switch (bc_modulo (first , second , & result , scale )) {
401
- case 0 :
402
- RETVAL_STR (bc_num2str_ex (result , scale ));
403
- break ;
404
- case -1 :
405
- zend_throw_exception_ex (zend_ce_division_by_zero_error , 0 , "Modulo by zero" );
406
- break ;
401
+ if (!bc_modulo (first , second , & result , scale )) {
402
+ zend_throw_exception_ex (zend_ce_division_by_zero_error , 0 , "Modulo by zero" );
403
+ goto cleanup ;
407
404
}
408
405
406
+ RETVAL_STR (bc_num2str_ex (result , scale ));
407
+
409
408
cleanup : {
410
409
bc_free_num (& first );
411
410
bc_free_num (& second );
@@ -417,16 +416,16 @@ PHP_FUNCTION(bcmod)
417
416
/* {{{ Returns the value of an arbitrary precision number raised to the power of another reduced by a modulus */
418
417
PHP_FUNCTION (bcpowmod )
419
418
{
420
- zend_string * left , * right , * modulus ;
419
+ zend_string * base_str , * exponent_str , * modulus_str ;
421
420
zend_long scale_param ;
422
421
bool scale_param_is_null = 1 ;
423
- bc_num first , second , mod , result ;
422
+ bc_num bc_base , bc_expo , bc_modulus , result ;
424
423
int scale = BCG (bc_precision );
425
424
426
425
ZEND_PARSE_PARAMETERS_START (3 , 4 )
427
- Z_PARAM_STR (left )
428
- Z_PARAM_STR (right )
429
- Z_PARAM_STR (modulus )
426
+ Z_PARAM_STR (base_str )
427
+ Z_PARAM_STR (exponent_str )
428
+ Z_PARAM_STR (modulus_str )
430
429
Z_PARAM_OPTIONAL
431
430
Z_PARAM_LONG_OR_NULL (scale_param , scale_param_is_null )
432
431
ZEND_PARSE_PARAMETERS_END ();
@@ -440,34 +439,53 @@ PHP_FUNCTION(bcpowmod)
440
439
scale = (int ) scale_param ;
441
440
}
442
441
443
- bc_init_num (& first );
444
- bc_init_num (& second );
445
- bc_init_num (& mod );
442
+ bc_init_num (& bc_base );
443
+ bc_init_num (& bc_expo );
444
+ bc_init_num (& bc_modulus );
446
445
bc_init_num (& result );
447
446
448
- if (php_str2num (& first , ZSTR_VAL (left )) == FAILURE ) {
447
+ if (php_str2num (& bc_base , ZSTR_VAL (base_str )) == FAILURE ) {
449
448
zend_argument_value_error (1 , "is not well-formed" );
450
449
goto cleanup ;
451
450
}
452
451
453
- if (php_str2num (& second , ZSTR_VAL (right )) == FAILURE ) {
452
+ if (php_str2num (& bc_expo , ZSTR_VAL (exponent_str )) == FAILURE ) {
454
453
zend_argument_value_error (2 , "is not well-formed" );
455
454
goto cleanup ;
456
455
}
457
456
458
- if (php_str2num (& mod , ZSTR_VAL (modulus )) == FAILURE ) {
457
+ if (php_str2num (& bc_modulus , ZSTR_VAL (modulus_str )) == FAILURE ) {
459
458
zend_argument_value_error (3 , "is not well-formed" );
460
459
goto cleanup ;
461
460
}
462
461
463
- if (bc_raisemod (first , second , mod , & result , scale ) == SUCCESS ) {
464
- RETVAL_STR (bc_num2str_ex (result , scale ));
462
+ raise_mod_status status = bc_raisemod (bc_base , bc_expo , bc_modulus , & result , scale );
463
+ switch (status ) {
464
+ case BASE_HAS_FRACTIONAL :
465
+ zend_argument_value_error (1 , "cannot have a fractional part" );
466
+ goto cleanup ;
467
+ case EXPO_HAS_FRACTIONAL :
468
+ zend_argument_value_error (2 , "cannot have a fractional part" );
469
+ goto cleanup ;
470
+ case EXPO_IS_NEGATIVE :
471
+ zend_argument_value_error (2 , "must be greater than or equal to 0" );
472
+ goto cleanup ;
473
+ case MOD_HAS_FRACTIONAL :
474
+ zend_argument_value_error (3 , "cannot have a fractional part" );
475
+ goto cleanup ;
476
+ case MOD_IS_ZERO :
477
+ zend_throw_exception_ex (zend_ce_division_by_zero_error , 0 , "Modulo by zero" );
478
+ goto cleanup ;
479
+ case OK :
480
+ RETVAL_STR (bc_num2str_ex (result , scale ));
481
+ break ;
482
+ EMPTY_SWITCH_DEFAULT_CASE ();
465
483
}
466
484
467
485
cleanup : {
468
- bc_free_num (& first );
469
- bc_free_num (& second );
470
- bc_free_num (& mod );
486
+ bc_free_num (& bc_base );
487
+ bc_free_num (& bc_expo );
488
+ bc_free_num (& bc_modulus );
471
489
bc_free_num (& result );
472
490
};
473
491
}
@@ -476,15 +494,15 @@ PHP_FUNCTION(bcpowmod)
476
494
/* {{{ Returns the value of an arbitrary precision number raised to the power of another */
477
495
PHP_FUNCTION (bcpow )
478
496
{
479
- zend_string * left , * right ;
497
+ zend_string * base_str , * exponent_str ;
480
498
zend_long scale_param ;
481
499
bool scale_param_is_null = 1 ;
482
- bc_num first , second , result ;
500
+ bc_num first , bc_exponent , result ;
483
501
int scale = BCG (bc_precision );
484
502
485
503
ZEND_PARSE_PARAMETERS_START (2 , 3 )
486
- Z_PARAM_STR (left )
487
- Z_PARAM_STR (right )
504
+ Z_PARAM_STR (base_str )
505
+ Z_PARAM_STR (exponent_str )
488
506
Z_PARAM_OPTIONAL
489
507
Z_PARAM_LONG_OR_NULL (scale_param , scale_param_is_null )
490
508
ZEND_PARSE_PARAMETERS_END ();
@@ -499,26 +517,37 @@ PHP_FUNCTION(bcpow)
499
517
}
500
518
501
519
bc_init_num (& first );
502
- bc_init_num (& second );
520
+ bc_init_num (& bc_exponent );
503
521
bc_init_num (& result );
504
522
505
- if (php_str2num (& first , ZSTR_VAL (left )) == FAILURE ) {
523
+ if (php_str2num (& first , ZSTR_VAL (base_str )) == FAILURE ) {
506
524
zend_argument_value_error (1 , "is not well-formed" );
507
525
goto cleanup ;
508
526
}
509
527
510
- if (php_str2num (& second , ZSTR_VAL (right )) == FAILURE ) {
528
+ if (php_str2num (& bc_exponent , ZSTR_VAL (exponent_str )) == FAILURE ) {
511
529
zend_argument_value_error (2 , "is not well-formed" );
512
530
goto cleanup ;
513
531
}
514
532
515
- bc_raise (first , second , & result , scale );
533
+ /* Check the exponent for scale digits and convert to a long. */
534
+ if (bc_exponent -> n_scale != 0 ) {
535
+ zend_argument_value_error (2 , "cannot have a fractional part" );
536
+ goto cleanup ;
537
+ }
538
+ long exponent = bc_num2long (bc_exponent );
539
+ if (exponent == 0 && (bc_exponent -> n_len > 1 || bc_exponent -> n_value [0 ] != 0 )) {
540
+ zend_argument_value_error (2 , "is too large" );
541
+ goto cleanup ;
542
+ }
543
+
544
+ bc_raise (first , exponent , & result , scale );
516
545
517
546
RETVAL_STR (bc_num2str_ex (result , scale ));
518
547
519
548
cleanup : {
520
549
bc_free_num (& first );
521
- bc_free_num (& second );
550
+ bc_free_num (& bc_exponent );
522
551
bc_free_num (& result );
523
552
};
524
553
}
0 commit comments