static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{ */ { zend_closure *closure = (zend_closure *)Z_OBJ_P(object); zval val; struct _zend_arg_info *arg_info = closure->func.common.arg_info; *is_temp = 0; if (closure->debug_info == NULL) { ALLOC_HASHTABLE(closure->debug_info); zend_hash_init(closure->debug_info, 8, NULL, ZVAL_PTR_DTOR, 0); } if (closure->debug_info->u.v.nApplyCount == 0) { if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) { HashTable *static_variables = closure->func.op_array.static_variables; ZVAL_ARR(&val, zend_array_dup(static_variables)); zend_hash_str_update(closure->debug_info, "static", sizeof("static")-1, &val); } if (Z_TYPE(closure->this_ptr) != IS_UNDEF) { Z_ADDREF(closure->this_ptr); zend_hash_str_update(closure->debug_info, "this", sizeof("this")-1, &closure->this_ptr); } if (arg_info && (closure->func.common.num_args || (closure->func.common.fn_flags & ZEND_ACC_VARIADIC))) { uint32_t i, num_args, required = closure->func.common.required_num_args; array_init(&val); num_args = closure->func.common.num_args; if (closure->func.common.fn_flags & ZEND_ACC_VARIADIC) { num_args++; } for (i = 0; i < num_args; i++) { zend_string *name; zval info; if (arg_info->name) { name = zend_strpprintf(0, "%s$%s", arg_info->pass_by_reference ? "&" : "", arg_info->name->val); } else { name = zend_strpprintf(0, "%s$param%d", arg_info->pass_by_reference ? "&" : "", i + 1); } ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>")); zend_hash_update(Z_ARRVAL(val), name, &info); zend_string_release(name); arg_info++; } zend_hash_str_update(closure->debug_info, "parameter", sizeof("parameter")-1, &val); } } return closure->debug_info; }
ZEND_API void ZEND_FASTCALL zval_copy_ctor_func(zval *zvalue) { if (EXPECTED(Z_TYPE_P(zvalue) == IS_ARRAY)) { ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue))); } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) { ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue))); CHECK_ZVAL_STRING(Z_STR_P(zvalue)); ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0)); } }
static void litespeed_php_import_environment_variables(zval *array_ptr) { char buf[128]; char **env, *p, *t = buf; size_t alloc_size = sizeof(buf); unsigned long nlen; /* ptrdiff_t is not portable */ if (Z_TYPE(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])) > 0 ) { zend_array_destroy(Z_ARR_P(array_ptr)); Z_ARR_P(array_ptr) = zend_array_dup(Z_ARR(PG(http_globals)[TRACK_VARS_ENV])); return; } else if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_SERVER]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])) > 0 ) { zend_array_destroy(Z_ARR_P(array_ptr)); Z_ARR_P(array_ptr) = zend_array_dup(Z_ARR(PG(http_globals)[TRACK_VARS_SERVER])); return; } for (env = environ; env != NULL && *env != NULL; env++) { p = strchr(*env, '='); if (!p) { /* malformed entry? */ continue; } nlen = p - *env; if (nlen >= alloc_size) { alloc_size = nlen + 64; t = (t == buf ? emalloc(alloc_size): erealloc(t, alloc_size)); } memcpy(t, *env, nlen); t[nlen] = '\0'; add_variable(t, nlen, p + 1, strlen( p + 1 ), array_ptr); } if (t != buf && t != NULL) { efree(t); } }
static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ { char *cmd; size_t cmd_len; zval *ret_code=NULL, *ret_array=NULL; int ret; ZEND_PARSE_PARAMETERS_START(1, (mode ? 2 : 3)) Z_PARAM_STRING(cmd, cmd_len) Z_PARAM_OPTIONAL if (!mode) { Z_PARAM_ZVAL_DEREF(ret_array) } Z_PARAM_ZVAL_DEREF(ret_code) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); if (!cmd_len) { php_error_docref(NULL, E_WARNING, "Cannot execute a blank command"); RETURN_FALSE; } if (strlen(cmd) != cmd_len) { php_error_docref(NULL, E_WARNING, "NULL byte detected. Possible attack"); RETURN_FALSE; } if (!ret_array) { ret = php_exec(mode, cmd, NULL, return_value); } else { if (Z_TYPE_P(ret_array) != IS_ARRAY) { zval_ptr_dtor(ret_array); array_init(ret_array); } else if (Z_REFCOUNT_P(ret_array) > 1) { zval_ptr_dtor(ret_array); ZVAL_ARR(ret_array, zend_array_dup(Z_ARR_P(ret_array))); } ret = php_exec(2, cmd, ret_array, return_value); } if (ret_code) { zval_ptr_dtor(ret_code); ZVAL_LONG(ret_code, ret); } }
ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_entry *scope, zend_class_entry *called_scope, zval *this_ptr) /* {{{ */ { zend_closure *closure; object_init_ex(res, zend_ce_closure); closure = (zend_closure *)Z_OBJ_P(res); if ((scope == NULL) && this_ptr && (Z_TYPE_P(this_ptr) != IS_UNDEF)) { /* use dummy scope if we're binding an object without specifying a scope */ /* maybe it would be better to create one for this purpose */ scope = zend_ce_closure; } if (func->type == ZEND_USER_FUNCTION) { memcpy(&closure->func, func, sizeof(zend_op_array)); closure->func.common.fn_flags |= ZEND_ACC_CLOSURE; if (closure->func.op_array.static_variables) { closure->func.op_array.static_variables = zend_array_dup(closure->func.op_array.static_variables); } /* Runtime cache is scope-dependent, so we cannot reuse it if the scope changed */ if (!closure->func.op_array.run_time_cache || func->common.scope != scope || (func->common.fn_flags & ZEND_ACC_NO_RT_ARENA) ) { if (!func->op_array.run_time_cache && (func->common.fn_flags & ZEND_ACC_CLOSURE)) { /* If a real closure is used for the first time, we create a shared runtime cache * and remember which scope it is for. */ func->common.scope = scope; func->op_array.run_time_cache = zend_arena_alloc(&CG(arena), func->op_array.cache_size); closure->func.op_array.run_time_cache = func->op_array.run_time_cache; } else { /* Otherwise, we use a non-shared runtime cache */ closure->func.op_array.run_time_cache = emalloc(func->op_array.cache_size); closure->func.op_array.fn_flags |= ZEND_ACC_NO_RT_ARENA; } memset(closure->func.op_array.run_time_cache, 0, func->op_array.cache_size); } if (closure->func.op_array.refcount) { (*closure->func.op_array.refcount)++; } } else { memcpy(&closure->func, func, sizeof(zend_internal_function)); closure->func.common.fn_flags |= ZEND_ACC_CLOSURE; /* wrap internal function handler to avoid memory leak */ if (UNEXPECTED(closure->func.internal_function.handler == zend_closure_internal_handler)) { /* avoid infinity recursion, by taking handler from nested closure */ zend_closure *nested = (zend_closure*)((char*)func - XtOffsetOf(zend_closure, func)); ZEND_ASSERT(nested->std.ce == zend_ce_closure); closure->orig_internal_handler = nested->orig_internal_handler; } else { closure->orig_internal_handler = closure->func.internal_function.handler; } closure->func.internal_function.handler = zend_closure_internal_handler; if (!func->common.scope) { /* if it's a free function, we won't set scope & this since they're meaningless */ this_ptr = NULL; scope = NULL; } } ZVAL_UNDEF(&closure->this_ptr); /* Invariant: * If the closure is unscoped or static, it has no bound object. */ closure->func.common.scope = scope; closure->called_scope = called_scope; if (scope) { closure->func.common.fn_flags |= ZEND_ACC_PUBLIC; if (this_ptr && Z_TYPE_P(this_ptr) == IS_OBJECT && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) { ZVAL_COPY(&closure->this_ptr, this_ptr); } } }
static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{ */ { zend_closure *closure = (zend_closure *)Z_OBJ_P(object); zval val; struct _zend_arg_info *arg_info = closure->func.common.arg_info; HashTable *debug_info; zend_bool zstr_args = (closure->func.type == ZEND_USER_FUNCTION) || (closure->func.common.fn_flags & ZEND_ACC_USER_ARG_INFO); *is_temp = 1; debug_info = zend_new_array(8); if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) { HashTable *static_variables = closure->func.op_array.static_variables; ZVAL_ARR(&val, zend_array_dup(static_variables)); zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val); } if (Z_TYPE(closure->this_ptr) != IS_UNDEF) { Z_ADDREF(closure->this_ptr); zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_THIS), &closure->this_ptr); } if (arg_info && (closure->func.common.num_args || (closure->func.common.fn_flags & ZEND_ACC_VARIADIC))) { uint32_t i, num_args, required = closure->func.common.required_num_args; array_init(&val); num_args = closure->func.common.num_args; if (closure->func.common.fn_flags & ZEND_ACC_VARIADIC) { num_args++; } for (i = 0; i < num_args; i++) { zend_string *name; zval info; if (arg_info->name) { if (zstr_args) { name = zend_strpprintf(0, "%s$%s", arg_info->pass_by_reference ? "&" : "", ZSTR_VAL(arg_info->name)); } else { name = zend_strpprintf(0, "%s$%s", arg_info->pass_by_reference ? "&" : "", ((zend_internal_arg_info*)arg_info)->name); } } else { name = zend_strpprintf(0, "%s$param%d", arg_info->pass_by_reference ? "&" : "", i + 1); } ZVAL_NEW_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>")); zend_hash_update(Z_ARRVAL(val), name, &info); zend_string_release_ex(name, 0); arg_info++; } zend_hash_str_update(debug_info, "parameter", sizeof("parameter")-1, &val); } return debug_info; }
/** public function ION\HTTP\Message::getHeaders() : array */ CLASS_METHOD(ION_HTTP_Message, getHeaders) { ion_http_message * message = ION_THIS_OBJECT(ion_http_message); RETURN_ARR(zend_array_dup(message->headers)); }