From: Xinchen Hui Date: Fri, 13 Feb 2015 05:18:14 +0000 (+0800) Subject: Merge branch 'PHP-5.6' X-Git-Tag: PRE_PHP7_EREG_MYSQL_REMOVALS~165 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=da7d94cd73a1f654bf49b16b5d1bf221255710de;p=php Merge branch 'PHP-5.6' Conflicts: ext/soap/soap.c ext/standard/basic_functions.c ext/zlib/zlib.c --- da7d94cd73a1f654bf49b16b5d1bf221255710de diff --cc Zend/zend_compile.c index 90c7ec34b3,c513e2ff88..c9b67021f0 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@@ -1199,81 -1532,262 +1199,82 @@@ static zend_bool zend_try_ct_eval_const } /* }}} */ -void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC) /* {{{ */ +static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend_string *name) /* {{{ */ { - zend_op_array op_array; - char *name = Z_STRVAL(function_name->u.constant); - int name_len = Z_STRLEN(function_name->u.constant); - int function_begin_line = function_token->u.op.opline_num; - zend_uint fn_flags; - const char *lcname; - zend_bool orig_interactive; - ALLOCA_FLAG(use_heap) + uint32_t fetch_type = zend_get_class_fetch_type(class_name); + zval *c; - if (is_method) { - if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) { - if ((Z_LVAL(fn_flags_znode->u.constant) & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) { - zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method %s::%s() must be omitted", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); - } - Z_LVAL(fn_flags_znode->u.constant) |= ZEND_ACC_ABSTRACT; /* propagates to the rest of the parser */ + if (CG(active_class_entry) && (fetch_type == ZEND_FETCH_CLASS_SELF || (fetch_type == ZEND_FETCH_CLASS_DEFAULT && zend_string_equals_ci(class_name, CG(active_class_entry)->name)))) { + c = zend_hash_find(&CG(active_class_entry)->constants_table, name); + } else if (fetch_type == ZEND_FETCH_CLASS_DEFAULT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) { + zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), class_name->val, class_name->len); + if (ce) { + c = zend_hash_find(&ce->constants_table, name); + } else { + return 0; } - fn_flags = Z_LVAL(fn_flags_znode->u.constant); /* must be done *after* the above check */ } else { - fn_flags = 0; - } - if ((fn_flags & ZEND_ACC_STATIC) && (fn_flags & ZEND_ACC_ABSTRACT) && !(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) { - zend_error(E_STRICT, "Static function %s%s%s() should not be abstract", is_method ? CG(active_class_entry)->name : "", is_method ? "::" : "", Z_STRVAL(function_name->u.constant)); + return 0; } - function_token->u.op_array = CG(active_op_array); - - orig_interactive = CG(interactive); - CG(interactive) = 0; - init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); - CG(interactive) = orig_interactive; - - op_array.function_name = name; - if (return_reference) { - op_array.fn_flags |= ZEND_ACC_RETURN_REFERENCE; + if (CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) { + return 0; } - op_array.fn_flags |= fn_flags; - - op_array.scope = is_method?CG(active_class_entry):NULL; - op_array.prototype = NULL; - - op_array.line_start = zend_get_compiled_lineno(TSRMLS_C); - - if (is_method) { - zend_ulong hash; - - lcname = zend_new_interned_string(zend_str_tolower_dup(name, name_len), name_len + 1, 1 TSRMLS_CC); - hash = str_hash(lcname, name_len); - if (zend_hash_quick_add(&CG(active_class_entry)->function_table, lcname, name_len+1, hash, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name); - } - - zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); - zend_init_compiler_context(TSRMLS_C); - - if (fn_flags & ZEND_ACC_ABSTRACT) { - CG(active_class_entry)->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS; - } - - if (!(fn_flags & ZEND_ACC_PPP_MASK)) { - fn_flags |= ZEND_ACC_PUBLIC; - } - - if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) { - if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __call() must have public visibility and cannot be static"); - } - } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) { - if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) { - zend_error(E_WARNING, "The magic method __callStatic() must have public visibility and be static"); - } - } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __get() must have public visibility and cannot be static"); - } - } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __set() must have public visibility and cannot be static"); - } - } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __unset() must have public visibility and cannot be static"); - } - } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __isset() must have public visibility and cannot be static"); - } - } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static"); - } - } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static"); - } - - } else if ((name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __debugInfo() must have public visibility and cannot be static"); - } - } - } else { - char *class_lcname; - class_lcname = do_alloca(CG(active_class_entry)->name_length + 1, use_heap); - zend_str_tolower_copy(class_lcname, CG(active_class_entry)->name, CG(active_class_entry)->name_length); - /* Improve after RC: cache the lowercase class name */ + /* Substitute case-sensitive (or lowercase) persistent class constants */ + if (c && Z_TYPE_P(c) < IS_OBJECT) { + ZVAL_DUP(zv, c); + return 1; + } - if ((CG(active_class_entry)->name_length == name_len) && ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != ZEND_ACC_TRAIT) && (!memcmp(class_lcname, lcname, name_len))) { - if (!CG(active_class_entry)->constructor) { - CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array); - } - } else if ((name_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)))) { - if (CG(active_class_entry)->constructor) { - zend_error(E_STRICT, "Redefining already defined constructor for class %s", CG(active_class_entry)->name); - } - CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1))) { - CG(active_class_entry)->destructor = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1))) { - CG(active_class_entry)->clone = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __call() must have public visibility and cannot be static"); - } - CG(active_class_entry)->__call = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) { - if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) { - zend_error(E_WARNING, "The magic method __callStatic() must have public visibility and be static"); - } - CG(active_class_entry)->__callstatic = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __get() must have public visibility and cannot be static"); - } - CG(active_class_entry)->__get = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __set() must have public visibility and cannot be static"); - } - CG(active_class_entry)->__set = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __unset() must have public visibility and cannot be static"); - } - CG(active_class_entry)->__unset = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __isset() must have public visibility and cannot be static"); - } - CG(active_class_entry)->__isset = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static"); - } - CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array); - } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static"); - } - } else if ((name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) { - if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { - zend_error(E_WARNING, "The magic method __debugInfo() must have public visibility and cannot be static"); - } - CG(active_class_entry)->__debugInfo = (zend_function *) CG(active_op_array); - } else if (!(fn_flags & ZEND_ACC_STATIC)) { - CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC; - } - free_alloca(class_lcname, use_heap); - } + return 0; +} ++/* }}} */ - str_efree(lcname); - } else { - zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); - zval key; - zval **ns_name; +void zend_init_list(void *result, void *item) /* {{{ */ +{ + void** list = emalloc(sizeof(void*) * 2); - if (CG(current_namespace)) { - /* Prefix function name with current namespace name */ - znode tmp; - - tmp.u.constant = *CG(current_namespace); - zval_copy_ctor(&tmp.u.constant); - zend_do_build_namespace_name(&tmp, &tmp, function_name TSRMLS_CC); - op_array.function_name = Z_STRVAL(tmp.u.constant); - name_len = Z_STRLEN(tmp.u.constant); - lcname = zend_str_tolower_dup(Z_STRVAL(tmp.u.constant), name_len); - } else { - lcname = zend_str_tolower_dup(name, name_len); - } + list[0] = item; + list[1] = NULL; - /* Function name must not conflict with import names */ - if (CG(current_import_function) && - zend_hash_find(CG(current_import_function), lcname, Z_STRLEN(function_name->u.constant)+1, (void**)&ns_name) == SUCCESS) { + *(void**)result = list; +} +/* }}} */ - char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name)); +void zend_add_to_list(void *result, void *item) /* {{{ */ +{ + void** list = *(void**)result; + size_t n = 0; - if (Z_STRLEN_PP(ns_name) != Z_STRLEN(function_name->u.constant) || - memcmp(tmp, lcname, Z_STRLEN(function_name->u.constant))) { - zend_error(E_COMPILE_ERROR, "Cannot declare function %s because the name is already in use", Z_STRVAL(function_name->u.constant)); - } - efree(tmp); + if (list) { + while (list[n]) { + n++; } - - opline->opcode = ZEND_DECLARE_FUNCTION; - opline->op1_type = IS_CONST; - build_runtime_defined_function_key(&key, lcname, name_len TSRMLS_CC); - opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC); - Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant))); - opline->op2_type = IS_CONST; - LITERAL_STRINGL(opline->op2, lcname, name_len, 1); - CALCULATE_LITERAL_HASH(opline->op2.constant); - opline->extended_value = ZEND_DECLARE_FUNCTION; - zend_hash_quick_update(CG(function_table), Z_STRVAL(key), Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)); - zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); - zend_init_compiler_context(TSRMLS_C); - str_efree(lcname); } - if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) { - zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + list = erealloc(list, sizeof(void*) * (n+2)); - opline->opcode = ZEND_EXT_NOP; - opline->lineno = function_begin_line; - SET_UNUSED(opline->op1); - SET_UNUSED(opline->op2); - } + list[n] = item; + list[n+1] = NULL; - { - /* Push a separator to the switch stack */ - zend_switch_entry switch_entry; + *(void**)result = list; +} +/* }}} */ - switch_entry.cond.op_type = IS_UNUSED; - switch_entry.default_case = 0; - switch_entry.control_var = 0; +void zend_do_extended_info(void) /* {{{ */ +{ + zend_op *opline; - zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry)); + if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) { + return; } - { - /* Push a separator to the foreach stack */ - zend_op dummy_opline; - - dummy_opline.result_type = IS_UNUSED; - - zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op)); - } + opline = get_next_op(CG(active_op_array)); - if (CG(doc_comment)) { - CG(active_op_array)->doc_comment = CG(doc_comment); - CG(active_op_array)->doc_comment_len = CG(doc_comment_len); - CG(doc_comment) = NULL; - CG(doc_comment_len) = 0; - } + opline->opcode = ZEND_EXT_STMT; + SET_UNUSED(opline->op1); + SET_UNUSED(opline->op2); } /* }}} */ @@@ -1309,17 -1828,151 +1310,30 @@@ void zend_do_extended_fcall_end(void) / } /* }}} */ -void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* {{{ */ -{ - char lcname[16]; - int name_len; - - zend_do_extended_info(TSRMLS_C); - zend_do_return(NULL, 0 TSRMLS_CC); - - pass_two(CG(active_op_array) TSRMLS_CC); - zend_release_labels(0 TSRMLS_CC); ++zend_bool zend_is_auto_global_str(char *name, size_t len) /* {{{ */ { ++ zend_auto_global *auto_global; + - if (CG(active_class_entry)) { - zend_check_magic_method_implementation(CG(active_class_entry), (zend_function*)CG(active_op_array), E_COMPILE_ERROR TSRMLS_CC); - } else { - /* we don't care if the function name is longer, in fact lowercasing only - * the beginning of the name speeds up the check process */ - name_len = strlen(CG(active_op_array)->function_name); - zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1)); - lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */ - if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)) && CG(active_op_array)->num_args != 1) { - zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME); ++ if ((auto_global = zend_hash_str_find_ptr(CG(auto_globals), name, len)) != NULL) { ++ if (auto_global->armed) { ++ auto_global->armed = auto_global->auto_global_callback(auto_global->name); + } ++ return 1; + } - - CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C); - CG(active_op_array) = function_token->u.op_array; - - - /* Pop the switch and foreach separators */ - zend_stack_del_top(&CG(switch_cond_stack)); - zend_stack_del_top(&CG(foreach_copy_stack)); ++ return 0; + } + /* }}} */ + -void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_uchar pass_by_reference, zend_bool is_variadic TSRMLS_DC) /* {{{ */ +zend_bool zend_is_auto_global(zend_string *name) /* {{{ */ { - zend_op *opline; - zend_arg_info *cur_arg_info; - znode var; + zend_auto_global *auto_global; - if (zend_is_auto_global(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant) TSRMLS_CC)) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s", Z_STRVAL(varname->u.constant)); - } else { - var.op_type = IS_CV; - var.u.op.var = lookup_cv(CG(active_op_array), Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), 0 TSRMLS_CC); - Z_STRVAL(varname->u.constant) = (char*)CG(active_op_array)->vars[var.u.op.var].name; - var.EA = 0; - if (CG(active_op_array)->vars[var.u.op.var].hash_value == THIS_HASHVAL && - Z_STRLEN(varname->u.constant) == sizeof("this")-1 && - !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")-1)) { - if (CG(active_op_array)->scope && - (CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); - } - CG(active_op_array)->this_var = var.u.op.var; - } - } - - if (CG(active_op_array)->fn_flags & ZEND_ACC_VARIADIC) { - zend_error_noreturn(E_COMPILE_ERROR, "Only the last parameter can be variadic"); - } - - if (is_variadic) { - if (op == ZEND_RECV_INIT) { - zend_error_noreturn(E_COMPILE_ERROR, "Variadic parameter cannot have a default value"); - } - - op = ZEND_RECV_VARIADIC; - CG(active_op_array)->fn_flags |= ZEND_ACC_VARIADIC; - } - - opline = get_next_op(CG(active_op_array) TSRMLS_CC); - CG(active_op_array)->num_args++; - opline->opcode = op; - SET_NODE(opline->result, &var); - opline->op1_type = IS_UNUSED; - opline->op1.num = CG(active_op_array)->num_args; - if (op == ZEND_RECV_INIT) { - SET_NODE(opline->op2, initialization); - } else { - SET_UNUSED(opline->op2); - if (!is_variadic) { - CG(active_op_array)->required_num_args = CG(active_op_array)->num_args; - } - } - CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args)); - cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1]; - cur_arg_info->name = zend_new_interned_string(estrndup(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)), Z_STRLEN(varname->u.constant) + 1, 1 TSRMLS_CC); - cur_arg_info->name_len = Z_STRLEN(varname->u.constant); - cur_arg_info->type_hint = 0; - cur_arg_info->pass_by_reference = pass_by_reference; - cur_arg_info->allow_null = 1; - cur_arg_info->is_variadic = is_variadic; - cur_arg_info->class_name = NULL; - cur_arg_info->class_name_len = 0; - - if (class_type->op_type != IS_UNUSED) { - cur_arg_info->allow_null = 0; - - if (class_type->u.constant.type != IS_NULL) { - if (class_type->u.constant.type == IS_ARRAY) { - cur_arg_info->type_hint = IS_ARRAY; - if (op == ZEND_RECV_INIT) { - if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { - cur_arg_info->allow_null = 1; - } else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) { - /* delay constant resolution and check to run-time */ - cur_arg_info->allow_null = 0; - } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY) { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL"); - } - } - } else if (class_type->u.constant.type == IS_CALLABLE) { - cur_arg_info->type_hint = IS_CALLABLE; - if (op == ZEND_RECV_INIT) { - if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { - cur_arg_info->allow_null = 1; - } else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) { - /* delay constant resolution and check to run-time */ - cur_arg_info->allow_null = 0; - } else { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL"); - } - } - } else { - cur_arg_info->type_hint = IS_OBJECT; - if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) { - zend_resolve_class_name(class_type TSRMLS_CC); - } - Z_STRVAL(class_type->u.constant) = (char*)zend_new_interned_string(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant) + 1, 1 TSRMLS_CC); - cur_arg_info->class_name = Z_STRVAL(class_type->u.constant); - cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant); - if (op == ZEND_RECV_INIT) { - if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { - cur_arg_info->allow_null = 1; - } else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) { - /* delay constant resolution and check to run-time */ - cur_arg_info->allow_null = 0; - } else { - zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); - } - } - } + if ((auto_global = zend_hash_find_ptr(CG(auto_globals), name)) != NULL) { + if (auto_global->armed) { + auto_global->armed = auto_global->auto_global_callback(auto_global->name); } + return 1; } + return 0; } /* }}} */ diff --cc Zend/zend_compile.h index 1104a29b82,3e9992f15b..0a4c146d28 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@@ -727,14 -726,15 +727,15 @@@ typedef struct _zend_auto_global zend_bool armed; } zend_auto_global; -ZEND_API int zend_register_auto_global(const char *name, uint name_len, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC); -ZEND_API void zend_activate_auto_globals(TSRMLS_D); -ZEND_API zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC); -ZEND_API zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hashval TSRMLS_DC); +ZEND_API int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback); +ZEND_API void zend_activate_auto_globals(void); +ZEND_API zend_bool zend_is_auto_global(zend_string *name); ++ZEND_API zend_bool zend_is_auto_global_str(char *name, size_t len); ZEND_API size_t zend_dirname(char *path, size_t len); -int zendlex(znode *zendlval TSRMLS_DC); +int zendlex(zend_parser_stack_elem *elem); -int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC); +int zend_add_literal(zend_op_array *op_array, zval *zv); /* BEGIN: OPCODES */ diff --cc ext/filter/filter.c index 85cfbf0913,86120bba56..9e2613257e --- a/ext/filter/filter.c +++ b/ext/filter/filter.c @@@ -534,19 -540,15 +534,15 @@@ static zval *php_filter_get_storage(zen break; case PARSE_SERVER: if (PG(auto_globals_jit)) { - zend_string *name = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0); - zend_is_auto_global(name); - zend_string_release(name); - zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); ++ zend_is_auto_global_str(ZEND_STRL("_SERVER")); } - array_ptr = IF_G(server_array); + array_ptr = &IF_G(server_array); break; case PARSE_ENV: if (PG(auto_globals_jit)) { - zend_string *name = zend_string_init("_ENV", sizeof("_ENV") - 1, 0); - zend_is_auto_global(name); - zend_string_release(name); - zend_is_auto_global("_ENV", sizeof("_ENV")-1 TSRMLS_CC); ++ zend_is_auto_global_str(ZEND_STRL("_ENV")); } - array_ptr = IF_G(env_array) ? IF_G(env_array) : PG(http_globals)[TRACK_VARS_ENV]; + array_ptr = &IF_G(env_array) ? &IF_G(env_array) : &PG(http_globals)[TRACK_VARS_ENV]; break; case PARSE_SESSION: /* FIXME: Implement session source */ diff --cc ext/soap/soap.c index 4308f3885f,406fdc0f54..6792c325ac --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@@ -1566,19 -1568,18 +1566,19 @@@ PHP_METHOD(SoapServer, handle if (ZEND_NUM_ARGS() == 0) { if (SG(request_info).request_body && 0 == php_stream_rewind(SG(request_info).request_body)) { - zval **server_vars, **encoding; + zval *server_vars, *encoding; php_stream_filter *zf = NULL; - zend_string *server = zend_string_init("_SERVER", sizeof("_SERVER")-1, 0); ++ zend_string *server = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0); - zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); - if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &server_vars) == SUCCESS && - Z_TYPE_PP(server_vars) == IS_ARRAY && - zend_hash_find(Z_ARRVAL_PP(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING"), (void **) &encoding)==SUCCESS && - Z_TYPE_PP(encoding) == IS_STRING) { + zend_is_auto_global(server); + if ((server_vars = zend_hash_find(&EG(symbol_table).ht, server)) != NULL && + Z_TYPE_P(server_vars) == IS_ARRAY && + (encoding = zend_hash_str_find(Z_ARRVAL_P(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING")-1)) != NULL && + Z_TYPE_P(encoding) == IS_STRING) { - if (strcmp(Z_STRVAL_PP(encoding),"gzip") == 0 - || strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 0 - || strcmp(Z_STRVAL_PP(encoding),"deflate") == 0 + if (strcmp(Z_STRVAL_P(encoding),"gzip") == 0 + || strcmp(Z_STRVAL_P(encoding),"x-gzip") == 0 + || strcmp(Z_STRVAL_P(encoding),"deflate") == 0 ) { zval filter_params; @@@ -2089,12 -2070,10 +2089,10 @@@ static void soap_server_fault_ex(sdlFun xmlDocDumpMemory(doc_return, &buf, &size); - server = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0); - zend_is_auto_global(server); - if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF && - if ((PG(http_globals)[TRACK_VARS_SERVER] || zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC)) && - zend_hash_find(PG(http_globals)[TRACK_VARS_SERVER]->value.ht, "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &agent_name) == SUCCESS && - Z_TYPE_PP(agent_name) == IS_STRING) { - if (strncmp(Z_STRVAL_PP(agent_name), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) { ++ if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) && + (agent_name = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1)) != NULL && + Z_TYPE_P(agent_name) == IS_STRING) { + if (strncmp(Z_STRVAL_P(agent_name), "Shockwave Flash", sizeof("Shockwave Flash")-1) == 0) { use_http_error_status = 0; } } diff --cc ext/standard/basic_functions.c index 940c9e4141,6552596438..dcd054fadb --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@@ -4229,17 -4227,14 +4229,17 @@@ PHP_FUNCTION(getopt /* Get argv from the global symbol table. We calculate argc ourselves * in order to be on the safe side, even though it is also available * from the symbol table. */ - if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF && - if ((PG(http_globals)[TRACK_VARS_SERVER] || zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC)) && - (zend_hash_find(Z_ARRVAL_P((PG(http_globals))[TRACK_VARS_SERVER]), "argv", sizeof("argv"), (void **) &args) != FAILURE || - zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void **) &args) != FAILURE) && Z_TYPE_PP(args) == IS_ARRAY ++ if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) && + ((args = zend_hash_str_find_ind(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1)) != NULL || + (args = zend_hash_str_find_ind(&EG(symbol_table).ht, "argv", sizeof("argv")-1)) != NULL) ) { int pos = 0; - zval **entry; + zval *entry; - argc = zend_hash_num_elements(Z_ARRVAL_PP(args)); + if (Z_TYPE_P(args) != IS_ARRAY) { + RETURN_FALSE; + } + argc = zend_hash_num_elements(Z_ARRVAL_P(args)); /* Attempt to allocate enough memory to hold all of the arguments * and a trailing NULL */ diff --cc ext/standard/browscap.c index e88a09e883,d3a094fdfb..217437ba8f --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@@ -462,17 -496,15 +462,14 @@@ PHP_FUNCTION(get_browser } if (agent_name == NULL) { - zend_string *key = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0); - zend_is_auto_global(key); - zend_string_release(key); - if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF || - (http_user_agent = zend_hash_str_find(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1)) == NULL - zend_is_auto_global("_SERVER", sizeof("_SERVER") - 1 TSRMLS_CC); - if (!PG(http_globals)[TRACK_VARS_SERVER] || - zend_hash_find(HASH_OF(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT"), (void **) &http_user_agent) == FAILURE ++ if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) || ++ (http_user_agent = zend_hash_str_find(Z_ARRVAL_P(&PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENT", sizeof("HTTP_USER_AGENT")-1)) == NULL ) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "HTTP_USER_AGENT variable is not set, cannot determine user agent name"); + php_error_docref(NULL, E_WARNING, "HTTP_USER_AGENT variable is not set, cannot determine user agent name"); RETURN_FALSE; } - agent_name = Z_STRVAL_PP(http_user_agent); - agent_name_len = Z_STRLEN_PP(http_user_agent); + agent_name = Z_STRVAL_P(http_user_agent); + agent_name_len = Z_STRLEN_P(http_user_agent); } lookup_browser_name = estrndup(agent_name, agent_name_len); diff --cc ext/zlib/zlib.c index 0b082048c0,d70198c674..67e67b114e --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@@ -77,20 -77,17 +77,17 @@@ static int php_zlib_output_conflict_che /* }}} */ /* {{{ php_zlib_output_encoding() */ -static int php_zlib_output_encoding(TSRMLS_D) +static int php_zlib_output_encoding(void) { - zval **enc; + zval *enc; if (!ZLIBG(compression_coding)) { - zend_string *name = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0); - zend_is_auto_global(name); - zend_string_release(name); - if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && - if ((PG(http_globals)[TRACK_VARS_SERVER] || zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC)) && - SUCCESS == zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING"), (void *) &enc)) { - convert_to_string(*enc); - if (strstr(Z_STRVAL_PP(enc), "gzip")) { ++ if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) && + (enc = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING") - 1))) { + convert_to_string(enc); + if (strstr(Z_STRVAL_P(enc), "gzip")) { ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_GZIP; - } else if (strstr(Z_STRVAL_PP(enc), "deflate")) { + } else if (strstr(Z_STRVAL_P(enc), "deflate")) { ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_DEFLATE; } } diff --cc sapi/cli/php_cli.c index ca0ea57fa7,db5ddb2567..8a8e113db0 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@@ -661,11 -673,11 +661,10 @@@ static int do_cli(int argc, char **argv int lineno = 0; const char *param_error=NULL; int hide_argv = 0; - zend_string *key; zend_try { - + CG(in_compilation) = 0; /* not initialized but needed for several options */ - EG(uninitialized_zval_ptr) = NULL; while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { switch (c) { @@@ -965,9 -979,7 +964,7 @@@ } } - key = zend_string_init("_SERVER", sizeof("_SERVER")-1, 0); - zend_is_auto_global(key); - zend_string_release(key); - zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC); ++ zend_is_auto_global_str(ZEND_STRL("_SERVER")); PG(during_request_startup) = 0; switch (behavior) { diff --cc sapi/phpdbg/phpdbg_utils.c index 357905fa06,7c7307a58b..ecec950c1b --- a/sapi/phpdbg/phpdbg_utils.c +++ b/sapi/phpdbg/phpdbg_utils.c @@@ -343,328 -453,3 +343,324 @@@ PHPDBG_API int phpdbg_get_terminal_widt #endif return columns; } /* }}} */ + +PHPDBG_API void phpdbg_set_async_io(int fd) { +#ifndef _WIN32 + int flags; + fcntl(STDIN_FILENO, F_SETOWN, getpid()); + flags = fcntl(STDIN_FILENO, F_GETFL); + fcntl(STDIN_FILENO, F_SETFL, flags | FASYNC); +#endif +} + +int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry **ce) { + if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { + char *lc_name, *lc_free; + int lc_length; + + if (name == NULL || !name_length) { + return FAILURE; + } + + lc_free = lc_name = emalloc(name_length + 1); + zend_str_tolower_copy(lc_name, name, name_length); + lc_length = name_length + 1; + + if (lc_name[0] == '\\') { + lc_name += 1; + lc_length -= 1; + } + + phpdbg_try_access { + *ce = zend_hash_str_find_ptr(EG(class_table), lc_name, lc_length); + } phpdbg_catch_access { + phpdbg_error("signalsegv", "class=\"%.*s\"", "Could not fetch class %.*s, invalid data source", name_length, name); + } phpdbg_end_try_access(); + + efree(lc_free); + } else { + zend_string *str_name = zend_string_init(name, name_length, 0); + *ce = zend_lookup_class(str_name); + efree(str_name); + } + + return ce ? SUCCESS : FAILURE; +} + +char *phpdbg_get_property_key(char *key) { + if (*key != 0) { + return key; + } + return strchr(key + 1, 0) + 1; +} + +static int phpdbg_parse_variable_arg_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv, phpdbg_parse_var_func callback) { + return callback(name, len, keyname, keylen, parent, zv); +} + +PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, zend_bool silent) { + return phpdbg_parse_variable_with_arg(input, len, parent, i, (phpdbg_parse_var_with_arg_func) phpdbg_parse_variable_arg_wrapper, silent, callback); +} + +PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, zend_bool silent, void *arg) { + int ret = FAILURE; + zend_bool new_index = 1; + char *last_index; + size_t index_len = 0; + zval *zv; + + if (len < 2 || *input != '$') { + goto error; + } + + while (i++ < len) { + if (i == len) { + new_index = 1; + } else { + switch (input[i]) { + case '[': + new_index = 1; + break; + case ']': + break; + case '>': + if (last_index[index_len - 1] == '-') { + new_index = 1; + index_len--; + } + break; + + default: + if (new_index) { + last_index = input + i; + new_index = 0; + } + if (input[i - 1] == ']') { + goto error; + } + index_len++; + } + } + + if (new_index && index_len == 0) { + zend_ulong numkey; + zend_string *strkey; + ZEND_HASH_FOREACH_KEY_PTR(parent, numkey, strkey, zv) { + while (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + } + + if (i == len || (i == len - 1 && input[len - 1] == ']')) { + char *key, *propkey; + size_t namelen, keylen; + char *name; + char *keyname = estrndup(last_index, index_len); + if (strkey) { + key = strkey->val; + keylen = strkey->len; + } else { + keylen = spprintf(&key, 0, "%llu", numkey); + } + propkey = phpdbg_get_property_key(key); + name = emalloc(i + keylen + 2); + namelen = sprintf(name, "%.*s%.*s%s", (int) i, input, keylen - (propkey - key), propkey, input[len - 1] == ']'?"]":""); + if (!strkey) { + efree(key); + } + + ret = callback(name, namelen, keyname, index_len, parent, zv, arg) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + } else if (Z_TYPE_P(zv) == IS_OBJECT) { + phpdbg_parse_variable_with_arg(input, len, Z_OBJPROP_P(zv), i, callback, silent, arg); + } else if (Z_TYPE_P(zv) == IS_ARRAY) { + phpdbg_parse_variable_with_arg(input, len, Z_ARRVAL_P(zv), i, callback, silent, arg); + } else { + /* Ignore silently */ + } + } ZEND_HASH_FOREACH_END(); + return ret; + } else if (new_index) { + char last_chr = last_index[index_len]; + last_index[index_len] = 0; + if (!(zv = zend_symtable_str_find(parent, last_index, index_len))) { + if (!silent) { + phpdbg_error("variable", "type=\"undefined\" variable=\"%.*s\"", "%.*s is undefined", (int) i, input); + } + return FAILURE; + } + while (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + } + + last_index[index_len] = last_chr; + if (i == len) { + char *name = estrndup(input, len); + char *keyname = estrndup(last_index, index_len); + + ret = callback(name, len, keyname, index_len, parent, zv, arg) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + } else if (Z_TYPE_P(zv) == IS_OBJECT) { + parent = Z_OBJPROP_P(zv); + } else if (Z_TYPE_P(zv) == IS_ARRAY) { + parent = Z_ARRVAL_P(zv); + } else { + phpdbg_error("variable", "type=\"notiterable\" variable=\"%.*s\"", "%.*s is nor an array nor an object", (int) i, input); + return FAILURE; + } + index_len = 0; + } + } + + return ret; + error: + phpdbg_error("variable", "type=\"invalidinput\"", "Malformed input"); + return FAILURE; +} + +int phpdbg_is_auto_global(char *name, int len) { - int ret; - zend_string *str = zend_string_init(name, len, 0); - ret = zend_is_auto_global(str); - efree(str); - return ret; ++ return zend_is_auto_global_str(name, len); +} + +static int phpdbg_xml_array_element_dump(zval *zv, zend_string *key, zend_ulong num) { + phpdbg_xml("len, key->val); + } else { /* numeric key */ + phpdbg_xml(" name=\"%ld\"", num); + } + } phpdbg_catch_access { + phpdbg_xml(" severity=\"error\" >"); + return 0; + } phpdbg_end_try_access(); + + phpdbg_xml(">"); + + phpdbg_xml_var_dump(zv); + + phpdbg_xml(""); + + return 0; +} + +static int phpdbg_xml_object_property_dump(zval *zv, zend_string *key, zend_ulong num) { + phpdbg_xml("len, key->val); + } + } else { /* numeric key */ + phpdbg_xml(" name=\"%ld\" protection=\"public\"", num); + } + } phpdbg_catch_access { + phpdbg_xml(" severity=\"error\" >"); + return 0; + } phpdbg_end_try_access(); + + phpdbg_xml(">"); + + phpdbg_xml_var_dump(zv); + + phpdbg_xml(""); + + return 0; +} + +#define COMMON (is_ref ? "&" : "") + +PHPDBG_API void phpdbg_xml_var_dump(zval *zv) { + HashTable *myht; + zend_string *class_name, *key; + zend_ulong num; + zval *val; + int (*element_dump_func)(zval *zv, zend_string *key, zend_ulong num); + zend_bool is_ref = 0; + + int is_temp; + + phpdbg_try_access { + is_ref = Z_ISREF_P(zv) && GC_REFCOUNT(Z_COUNTED_P(zv)) > 1; + ZVAL_DEREF(zv); + + switch (Z_TYPE_P(zv)) { + case IS_TRUE: + phpdbg_xml("", COMMON); + break; + case IS_FALSE: + phpdbg_xml("", COMMON); + break; + case IS_NULL: + phpdbg_xml("", COMMON); + break; + case IS_LONG: + phpdbg_xml("", COMMON, Z_LVAL_P(zv)); + break; + case IS_DOUBLE: + phpdbg_xml("", COMMON, (int) EG(precision), Z_DVAL_P(zv)); + break; + case IS_STRING: + phpdbg_xml("", COMMON, Z_STRLEN_P(zv), Z_STRLEN_P(zv), Z_STRVAL_P(zv)); + break; + case IS_ARRAY: + myht = Z_ARRVAL_P(zv); + if (ZEND_HASH_APPLY_PROTECTION(myht) && ++myht->u.v.nApplyCount > 1) { + phpdbg_xml(""); + --myht->u.v.nApplyCount; + break; + } + phpdbg_xml("", COMMON, zend_hash_num_elements(myht)); + element_dump_func = phpdbg_xml_array_element_dump; + is_temp = 0; + goto head_done; + case IS_OBJECT: + myht = Z_OBJDEBUG_P(zv, is_temp); + if (myht && ++myht->u.v.nApplyCount > 1) { + phpdbg_xml(""); + --myht->u.v.nApplyCount; + break; + } + + class_name = Z_OBJ_HANDLER_P(zv, get_class_name)(Z_OBJ_P(zv)); + phpdbg_xml("", COMMON, class_name->len, class_name->val, Z_OBJ_HANDLE_P(zv), myht ? zend_hash_num_elements(myht) : 0); + zend_string_release(class_name); + + element_dump_func = phpdbg_xml_object_property_dump; +head_done: + if (myht) { + ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) { + element_dump_func(val, key, num); + } ZEND_HASH_FOREACH_END(); + zend_hash_apply_with_arguments(myht, (apply_func_args_t) element_dump_func, 0); + --myht->u.v.nApplyCount; + if (is_temp) { + zend_hash_destroy(myht); + efree(myht); + } + } + if (Z_TYPE_P(zv) == IS_ARRAY) { + phpdbg_xml(""); + } else { + phpdbg_xml(""); + } + break; + case IS_RESOURCE: { + const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(zv)); + phpdbg_xml("", COMMON, Z_RES_P(zv)->handle, type_name ? type_name : "unknown"); + break; + } + default: + break; + } + } phpdbg_end_try_access(); +}