diff --git a/Zend/zend.h b/Zend/zend.h index 1ac7914c756..85e1287d503 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -703,6 +703,15 @@ END_EXTERN_C() #define SEPARATE_ZVAL_IF_REF(zv) \ if (Z_ISREF_P(zv)) { \ + if (Z_REFCOUNT_P(zv) == 1) { \ + zend_reference *ref = Z_REF_P(zv); \ + ZVAL_COPY_VALUE(zv, &ref->val); \ + efree(ref); \ + } else { \ + zval *ref = Z_REFVAL_P(zv); \ + Z_DELREF_P(zv); \ + ZVAL_DUP(zv, ref); \ + } \ SEPARATE_ZVAL(zv); \ } diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 32f60dc2327..8580e5d2b43 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1125,6 +1125,11 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destro static int zval_update_class_constant(zval *pp, int is_static, int offset TSRMLS_DC) /* {{{ */ { +// zval *p = pp; + + if (Z_TYPE_P(pp) == IS_REFERENCE) { + pp = Z_REFVAL_P(pp); + } if (IS_CONSTANT_TYPE(Z_TYPE_P(pp))) { zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry); @@ -3736,7 +3741,7 @@ ZEND_API void zend_update_property_str(zend_class_entry *scope, zval *object, co { zval tmp; - ZVAL_STR(&tmp, STR_COPY(value)); + ZVAL_STR(&tmp, value); zend_update_property(scope, object, name, name_length, &tmp TSRMLS_CC); } /* }}} */ diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 20477af906e..a32d853c255 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1659,8 +1659,9 @@ ZEND_FUNCTION(get_declared_interfaces) /* }}} */ -static int copy_function_name(zend_function *func TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +static int copy_function_name(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) { + zend_function *func = Z_PTR_P(zv); zval *internal_ar = va_arg(args, zval *), *user_ar = va_arg(args, zval *); diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 46894c6106a..85273d5a06f 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -339,7 +339,9 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_ } info_len = zend_spprintf(&info, 0, "%s", i >= required ? "" : ""); - add_assoc_stringl_ex(&val, name, name_len, info, info_len, 0); +//??? TODO: avoid reallocation + add_assoc_stringl_ex(&val, name, name_len, info, info_len, 1); + efree(info); efree(name); arg_info++; } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 435ab517ad4..ca9ee341f41 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7021,7 +7021,7 @@ void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRM //??? Z_TYPE(result->u.constant) = IS_STRING; //??? Z_STRVAL(result->u.constant) = NULL; //??? Z_STRLEN(result->u.constant) = 0; - ZVAL_UNDEF(&result->u.constant); + ZVAL_EMPTY_STRING(&result->u.constant); } /* prefix = result */ zend_do_build_full_name(NULL, result, name, 0 TSRMLS_CC); diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index cf9802b498d..0f0af50b662 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -488,12 +488,12 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC) } /* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */ - if ((c->name->len == sizeof("__COMPILER_HALT_OFFSET__") + if ((c->name->len == sizeof("__COMPILER_HALT_OFFSET__")-1 && !memcmp(name->val, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) || zend_hash_add_mem(EG(zend_constants), name, c, sizeof(zend_constant)) == NULL) { /* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */ - if (c->name->val[0] == '\0' && c->name->len > sizeof("\0__COMPILER_HALT_OFFSET__") + if (c->name->val[0] == '\0' && c->name->len > sizeof("\0__COMPILER_HALT_OFFSET__")-1 && memcmp(name->val, "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) { //??? name++; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 92071878dda..dc362369e68 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4585,6 +4585,9 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST| container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS); offset = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -4664,7 +4667,7 @@ ZEND_VM_C_LABEL(num_index_prop): zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9a461f5c119..7073a1f6f66 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -15759,6 +15759,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -15838,7 +15841,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -17774,6 +17777,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -17853,7 +17859,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -20183,6 +20189,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -20262,7 +20271,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -23372,6 +23381,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -23451,7 +23463,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -24815,6 +24827,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON container = _get_obj_zval_ptr_unused(TSRMLS_C); offset = opline->op2.zv; + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -24894,7 +24909,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -26090,6 +26105,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP container = _get_obj_zval_ptr_unused(TSRMLS_C); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -26169,7 +26187,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -27365,6 +27383,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR container = _get_obj_zval_ptr_unused(TSRMLS_C); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -27444,7 +27465,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -29040,6 +29061,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV( container = _get_obj_zval_ptr_unused(TSRMLS_C); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -29119,7 +29143,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -32465,6 +32489,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = opline->op2.zv; + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -32544,7 +32571,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -34355,6 +34382,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -34434,7 +34464,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -36639,6 +36669,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -36718,7 +36751,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); @@ -39572,6 +39605,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + if (Z_TYPE_P(container) == IS_REFERENCE) { + container = Z_REFVAL_P(container); + } if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; @@ -39651,7 +39687,7 @@ num_index_prop: zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { - if (Z_TYPE_P(offset) <= IS_BOOL /* simple scalar types */ + if (!Z_REFCOUNTED_P(offset) /* simple scalar types */ || (Z_TYPE_P(offset) == IS_STRING /* or numeric string */ && IS_LONG == is_numeric_string(Z_STRVAL_P(offset), Z_STRLEN_P(offset), NULL, NULL, 0))) { ZVAL_DUP(&tmp, offset); diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index c27f3f7eb10..0a62f6f0b29 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -96,6 +96,7 @@ static void php_free_pcre_cache(zval *data) /* {{{ */ if ((void*)pce->tables) pefree((void*)pce->tables, 1); pefree(pce->locale, 1); #endif + pefree(pce, 1); } /* }}} */ @@ -1392,8 +1393,10 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { +//??? TODO: reimpplement to avoid double reallocation //??? RETVAL_STRINGL(result, result_len, 0); RETVAL_STRINGL(result, result_len); + efree(result); } else { efree(result); }