@@ -3701,6 +3701,7 @@ PHP_FUNCTION(mb_convert_variables)
3701
3701
const mbfl_encoding * * elist ;
3702
3702
char * to_enc ;
3703
3703
void * ptmp ;
3704
+ int recursion_error = 0 ;
3704
3705
3705
3706
if (zend_parse_parameters (ZEND_NUM_ARGS (), "sz+" , & to_enc , & to_enc_len , & zfrom_enc , & args , & argc ) == FAILURE ) {
3706
3707
return ;
@@ -3765,6 +3766,11 @@ PHP_FUNCTION(mb_convert_variables)
3765
3766
target_hash = HASH_OF (var );
3766
3767
if (target_hash != NULL ) {
3767
3768
while ((hash_entry = zend_hash_get_current_data (target_hash )) != NULL ) {
3769
+ if (++ target_hash -> u .v .nApplyCount > 1 ) {
3770
+ -- target_hash -> u .v .nApplyCount ;
3771
+ recursion_error = 1 ;
3772
+ goto detect_end ;
3773
+ }
3768
3774
zend_hash_move_forward (target_hash );
3769
3775
if (Z_TYPE_P (hash_entry ) == IS_INDIRECT ) {
3770
3776
hash_entry = Z_INDIRECT_P (hash_entry );
@@ -3805,6 +3811,19 @@ PHP_FUNCTION(mb_convert_variables)
3805
3811
from_encoding = mbfl_encoding_detector_judge2 (identd );
3806
3812
mbfl_encoding_detector_delete (identd );
3807
3813
}
3814
+ if (recursion_error ) {
3815
+ while (stack_level -- && (var = & stack [stack_level ])) {
3816
+ if (HASH_OF (var )-> u .v .nApplyCount > 1 ) {
3817
+ HASH_OF (var )-> u .v .nApplyCount -- ;
3818
+ }
3819
+ }
3820
+ efree (stack );
3821
+ if (elist != NULL ) {
3822
+ efree ((void * )elist );
3823
+ }
3824
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cannot handle recursive references" );
3825
+ RETURN_FALSE ;
3826
+ }
3808
3827
efree (stack );
3809
3828
3810
3829
if (!from_encoding ) {
@@ -3859,6 +3878,11 @@ PHP_FUNCTION(mb_convert_variables)
3859
3878
hash_entry = hash_entry_ptr ;
3860
3879
ZVAL_DEREF (hash_entry );
3861
3880
if (Z_TYPE_P (hash_entry ) == IS_ARRAY || Z_TYPE_P (hash_entry ) == IS_OBJECT ) {
3881
+ if (++ (HASH_OF (hash_entry )-> u .v .nApplyCount ) > 1 ) {
3882
+ -- (HASH_OF (hash_entry )-> u .v .nApplyCount );
3883
+ recursion_error = 1 ;
3884
+ goto conv_end ;
3885
+ }
3862
3886
if (stack_level >= stack_max ) {
3863
3887
stack_max += PHP_MBSTR_STACK_BLOCK_SIZE ;
3864
3888
ptmp = erealloc (stack , sizeof (zval ) * stack_max );
@@ -3898,10 +3922,22 @@ PHP_FUNCTION(mb_convert_variables)
3898
3922
}
3899
3923
}
3900
3924
}
3901
- efree (stack );
3902
3925
3926
+ conv_end :
3903
3927
MBSTRG (illegalchars ) += mbfl_buffer_illegalchars (convd );
3904
3928
mbfl_buffer_converter_delete (convd );
3929
+
3930
+ if (recursion_error ) {
3931
+ while (stack_level -- && (var = & stack [stack_level ])) {
3932
+ if (HASH_OF (var )-> u .v .nApplyCount > 1 ) {
3933
+ HASH_OF (var )-> u .v .nApplyCount -- ;
3934
+ }
3935
+ }
3936
+ efree (stack );
3937
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Cannot handle recursive references" );
3938
+ RETURN_FALSE ;
3939
+ }
3940
+ efree (stack );
3905
3941
}
3906
3942
3907
3943
if (from_encoding ) {
0 commit comments