const mbfl_encoding **elist;
char *to_enc;
void *ptmp;
+ int recursion_error = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ+", &to_enc, &to_enc_len, &zfrom_enc, &args, &argc) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz+", &to_enc, &to_enc_len, &zfrom_enc, &args, &argc) == FAILURE) {
return;
}
}
} else {
stack_level--;
- var = stack[stack_level];
+ var = &stack[stack_level];
}
- if (Z_TYPE_PP(var) == IS_ARRAY || Z_TYPE_PP(var) == IS_OBJECT) {
- target_hash = HASH_OF(*var);
+ if (Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT) {
+ target_hash = HASH_OF(var);
if (target_hash != NULL) {
- while (zend_hash_get_current_data(target_hash, (void **) &hash_entry) != FAILURE) {
- if (++target_hash->nApplyCount > 1) {
- --target_hash->nApplyCount;
+ while ((hash_entry = zend_hash_get_current_data(target_hash)) != NULL) {
++ if (++target_hash->u.v.nApplyCount > 1) {
++ --target_hash->u.v.nApplyCount;
+ recursion_error = 1;
+ goto detect_end;
+ }
zend_hash_move_forward(target_hash);
- if (Z_TYPE_PP(hash_entry) == IS_ARRAY || Z_TYPE_PP(hash_entry) == IS_OBJECT) {
+ if (Z_TYPE_P(hash_entry) == IS_INDIRECT) {
+ hash_entry = Z_INDIRECT_P(hash_entry);
+ }
+ ZVAL_DEREF(hash_entry);
+ if (Z_TYPE_P(hash_entry) == IS_ARRAY || Z_TYPE_P(hash_entry) == IS_OBJECT) {
if (stack_level >= stack_max) {
stack_max += PHP_MBSTR_STACK_BLOCK_SIZE;
- ptmp = erealloc(stack, sizeof(zval **)*stack_max);
- stack = (zval ***)ptmp;
+ ptmp = erealloc(stack, sizeof(zval) * stack_max);
+ stack = (zval *)ptmp;
}
- stack[stack_level] = var;
+ ZVAL_COPY_VALUE(&stack[stack_level], var);
stack_level++;
var = hash_entry;
- target_hash = HASH_OF(*var);
+ target_hash = HASH_OF(var);
if (target_hash != NULL) {
zend_hash_internal_pointer_reset(target_hash);
continue;
from_encoding = mbfl_encoding_detector_judge2(identd);
mbfl_encoding_detector_delete(identd);
}
- while(stack_level-- && (var = stack[stack_level])) {
- if (HASH_OF(*var)->nApplyCount > 1) {
- HASH_OF(*var)->nApplyCount--;
+ if (recursion_error) {
- efree(args);
++ while(stack_level-- && (var = &stack[stack_level])) {
++ if (HASH_OF(var)->u.v.nApplyCount > 1) {
++ HASH_OF(var)->u.v.nApplyCount--;
+ }
+ }
+ efree(stack);
+ if (elist != NULL) {
+ efree((void *)elist);
+ }
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot handle recursive references");
+ RETURN_FALSE;
+ }
efree(stack);
if (!from_encoding) {
}
} else {
stack_level--;
- var = stack[stack_level];
+ var = &stack[stack_level];
}
- if (Z_TYPE_PP(var) == IS_ARRAY || Z_TYPE_PP(var) == IS_OBJECT) {
- target_hash = HASH_OF(*var);
+ if (Z_TYPE_P(var) == IS_ARRAY || Z_TYPE_P(var) == IS_OBJECT) {
+ target_hash = HASH_OF(var);
if (target_hash != NULL) {
- while (zend_hash_get_current_data(target_hash, (void **) &hash_entry) != FAILURE) {
+ while ((hash_entry_ptr = zend_hash_get_current_data(target_hash)) != NULL) {
zend_hash_move_forward(target_hash);
- if (Z_TYPE_PP(hash_entry) == IS_ARRAY || Z_TYPE_PP(hash_entry) == IS_OBJECT) {
- if (++(HASH_OF(*hash_entry)->nApplyCount) > 1) {
- --(HASH_OF(*hash_entry)->nApplyCount);
+ if (Z_TYPE_P(hash_entry_ptr) == IS_INDIRECT) {
+ hash_entry_ptr = Z_INDIRECT_P(hash_entry_ptr);
+ }
+ hash_entry = hash_entry_ptr;
+ ZVAL_DEREF(hash_entry);
+ if (Z_TYPE_P(hash_entry) == IS_ARRAY || Z_TYPE_P(hash_entry) == IS_OBJECT) {
++ if (++(HASH_OF(hash_entry)->u.v.nApplyCount) > 1) {
++ --(HASH_OF(hash_entry)->u.v.nApplyCount);
+ recursion_error = 1;
+ goto conv_end;
+ }
if (stack_level >= stack_max) {
stack_max += PHP_MBSTR_STACK_BLOCK_SIZE;
- ptmp = erealloc(stack, sizeof(zval **)*stack_max);
- stack = (zval ***)ptmp;
+ ptmp = erealloc(stack, sizeof(zval) * stack_max);
+ stack = (zval *)ptmp;
}
- stack[stack_level] = var;
+ ZVAL_COPY_VALUE(&stack[stack_level], var);
stack_level++;
var = hash_entry;
- target_hash = HASH_OF(*var);
+ SEPARATE_ZVAL(hash_entry);
+ target_hash = HASH_OF(var);
if (target_hash != NULL) {
zend_hash_internal_pointer_reset(target_hash);
continue;
}
}
}
- efree(stack);
+ conv_end:
MBSTRG(illegalchars) += mbfl_buffer_illegalchars(convd);
mbfl_buffer_converter_delete(convd);
- while(stack_level-- && (var = stack[stack_level])) {
- if (HASH_OF(*var)->nApplyCount > 1) {
- HASH_OF(*var)->nApplyCount--;
+
+ if (recursion_error) {
- efree(args);
++ while(stack_level-- && (var = &stack[stack_level])) {
++ if (HASH_OF(var)->u.v.nApplyCount > 1) {
++ HASH_OF(var)->u.v.nApplyCount--;
+ }
+ }
+ efree(stack);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot handle recursive references");
+ RETURN_FALSE;
+ }
+ efree(stack);
}
- efree(args);
-
if (from_encoding) {
- RETURN_STRING(from_encoding->name, 1);
+ RETURN_STRING(from_encoding->name);
} else {
RETURN_FALSE;
}