/* error already emitted, but let's emit another more relevant */ do_from_zval_err(ctx, "could not resolve address '%s' to get an AF_INET6 " "address", Z_STRVAL_P(zaddr_str)); } zend_tmp_string_release(tmp_addr_str); } static void to_zval_read_sin6_addr(const char *data, zval *zv, res_context *ctx) { const struct in6_addr *addr = (const struct in6_addr *)data; socklen_t size = INET6_ADDRSTRLEN; zend_string *str = zend_string_alloc(size - 1, 0); memset(ZSTR_VAL(str), '\0', size); ZVAL_NEW_STR(zv, str); if (inet_ntop(AF_INET6, addr, Z_STRVAL_P(zv), size) == NULL) { do_to_zval_err(ctx, "could not convert IPv6 address to string " "(errno %d)", errno); return; } Z_STRLEN_P(zv) = strlen(Z_STRVAL_P(zv)); } static const field_descriptor descriptors_sockaddr_in6[] = { {"family", sizeof("family"), 0, offsetof(struct sockaddr_in6, sin6_family), from_zval_write_sa_family, to_zval_read_sa_family}, {"addr", sizeof("addr"), 0, offsetof(struct sockaddr_in6, sin6_addr), from_zval_write_sin6_addr, to_zval_read_sin6_addr}, {"port", sizeof("port"), 0, offsetof(struct sockaddr_in6, sin6_port), from_zval_write_net_uint16, to_zval_read_net_uint16}, {"flowinfo", sizeof("flowinfo"), 0, offsetof(struct sockaddr_in6, sin6_flowinfo), from_zval_write_uint32, to_zval_read_uint32}, {"scope_id", sizeof("scope_id"), 0, offsetof(struct sockaddr_in6, sin6_scope_id), from_zval_write_uint32, to_zval_read_uint32}, {0} }; static void from_zval_write_sockaddr_in6(const zval *container, char *sockaddr6, ser_context *ctx) { from_zval_write_aggregation(container, sockaddr6, descriptors_sockaddr_in6, ctx); } static void to_zval_read_sockaddr_in6(const char *data, zval *zv, res_context *ctx) { to_zval_read_aggregation(data, zv, descriptors_sockaddr_in6, ctx); } #endif /* HAVE_IPV6 */ static void from_zval_write_sun_path(const zval *path, char *sockaddr_un_c, ser_context *ctx) { zend_string *path_str, *tmp_path_str; struct sockaddr_un *saddr = (struct sockaddr_un*)sockaddr_un_c; path_str = zval_get_tmp_string((zval *) path, &tmp_path_str); /* code in this file relies on the path being nul terminated, even though * this is not required, at least on linux for abstract paths. It also * assumes that the path is not empty */ if (ZSTR_LEN(path_str) == 0) { do_from_zval_err(ctx, "%s", "the path is cannot be empty"); zend_tmp_string_release(tmp_path_str); return; } if (ZSTR_LEN(path_str) >= sizeof(saddr->sun_path)) { do_from_zval_err(ctx, "the path is too long, the maximum permitted " "length is %zd", sizeof(saddr->sun_path) - 1); zend_tmp_string_release(tmp_path_str); return; } memcpy(&saddr->sun_path, ZSTR_VAL(path_str), ZSTR_LEN(path_str)); saddr->sun_path[ZSTR_LEN(path_str)] = '\0'; zend_tmp_string_release(tmp_path_str); }
ZEND_API size_t zend_print_zval(zval *expr, int indent) /* {{{ */ { zend_string *tmp_str; zend_string *str = zval_get_tmp_string(expr, &tmp_str); size_t len = ZSTR_LEN(str); if (len != 0) { zend_write(ZSTR_VAL(str), len); } zend_tmp_string_release(tmp_str); return len; }
/* {{{ proto Closure Closure::bind(callable old, object to [, mixed scope]) Create a closure from another one and bind to another object and scope */ ZEND_METHOD(Closure, bind) { zval *newthis, *zclosure, *scope_arg = NULL; zend_closure *closure; zend_class_entry *ce, *called_scope; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oo!|z", &zclosure, zend_ce_closure, &newthis, &scope_arg) == FAILURE) { return; } closure = (zend_closure *)Z_OBJ_P(zclosure); if (scope_arg != NULL) { /* scope argument was given */ if (Z_TYPE_P(scope_arg) == IS_OBJECT) { ce = Z_OBJCE_P(scope_arg); } else if (Z_TYPE_P(scope_arg) == IS_NULL) { ce = NULL; } else { zend_string *tmp_class_name; zend_string *class_name = zval_get_tmp_string(scope_arg, &tmp_class_name); if (zend_string_equals_literal(class_name, "static")) { ce = closure->func.common.scope; } else if ((ce = zend_lookup_class_ex(class_name, NULL, 1)) == NULL) { zend_error(E_WARNING, "Class '%s' not found", ZSTR_VAL(class_name)); zend_string_release_ex(class_name, 0); RETURN_NULL(); } zend_tmp_string_release(tmp_class_name); } } else { /* scope argument not given; do not change the scope by default */ ce = closure->func.common.scope; } if (!zend_valid_closure_binding(closure, newthis, ce)) { return; } if (newthis) { called_scope = Z_OBJCE_P(newthis); } else { called_scope = ce; } zend_create_closure(return_value, &closure->func, ce, called_scope, newthis); }
static void from_zval_write_sin6_addr(const zval *zaddr_str, char *addr6, ser_context *ctx) { int res; struct sockaddr_in6 saddr6 = {0}; zend_string *addr_str, *tmp_addr_str; addr_str = zval_get_tmp_string((zval *) zaddr_str, &tmp_addr_str); res = php_set_inet6_addr(&saddr6, ZSTR_VAL(addr_str), ctx->sock); if (res) { memcpy(addr6, &saddr6.sin6_addr, sizeof saddr6.sin6_addr); } else { /* error already emitted, but let's emit another more relevant */ do_from_zval_err(ctx, "could not resolve address '%s' to get an AF_INET6 " "address", Z_STRVAL_P(zaddr_str)); } zend_tmp_string_release(tmp_addr_str); }
/* {{{ php_url_encode_hash */ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, const char *num_prefix, size_t num_prefix_len, const char *key_prefix, size_t key_prefix_len, const char *key_suffix, size_t key_suffix_len, zval *type, char *arg_sep, int enc_type) { zend_string *key = NULL; char *newprefix, *p; const char *prop_name; size_t arg_sep_len, newprefix_len, prop_len; zend_ulong idx; zval *zdata = NULL; if (!ht) { return FAILURE; } if (GC_IS_RECURSIVE(ht)) { /* Prevent recursion */ return SUCCESS; } if (!arg_sep) { arg_sep = INI_STR("arg_separator.output"); if (!arg_sep || !strlen(arg_sep)) { arg_sep = URL_DEFAULT_ARG_SEP; } } arg_sep_len = strlen(arg_sep); ZEND_HASH_FOREACH_KEY_VAL(ht, idx, key, zdata) { zend_bool is_dynamic = 1; if (Z_TYPE_P(zdata) == IS_INDIRECT) { zdata = Z_INDIRECT_P(zdata); if (Z_ISUNDEF_P(zdata)) { continue; } is_dynamic = 0; } /* handling for private & protected object properties */ if (key) { prop_name = ZSTR_VAL(key); prop_len = ZSTR_LEN(key); if (type != NULL && zend_check_property_access(Z_OBJ_P(type), key, is_dynamic) != SUCCESS) { /* property not visible in this scope */ continue; } if (ZSTR_VAL(key)[0] == '\0' && type != NULL) { const char *tmp; zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len); } else { prop_name = ZSTR_VAL(key); prop_len = ZSTR_LEN(key); } } else { prop_name = NULL; prop_len = 0; } ZVAL_DEREF(zdata); if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) { if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } newprefix_len = key_suffix_len + ZSTR_LEN(ekey) + key_prefix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, ZSTR_VAL(ekey), ZSTR_LEN(ekey)); p += ZSTR_LEN(ekey); zend_string_free(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } else { char *ekey; size_t ekey_len; /* Is an integer key */ ekey_len = spprintf(&ekey, 0, ZEND_LONG_FMT, idx); newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */; newprefix = emalloc(newprefix_len + 1); p = newprefix; if (key_prefix) { memcpy(p, key_prefix, key_prefix_len); p += key_prefix_len; } memcpy(p, num_prefix, num_prefix_len); p += num_prefix_len; memcpy(p, ekey, ekey_len); p += ekey_len; efree(ekey); if (key_suffix) { memcpy(p, key_suffix, key_suffix_len); p += key_suffix_len; } *(p++) = '%'; *(p++) = '5'; *(p++) = 'B'; *p = '\0'; } if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { GC_PROTECT_RECURSION(ht); } php_url_encode_hash_ex(HASH_OF(zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_P(zdata) == IS_OBJECT ? zdata : NULL), arg_sep, enc_type); if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { GC_UNPROTECT_RECURSION(ht); } efree(newprefix); } else if (Z_TYPE_P(zdata) == IS_NULL || Z_TYPE_P(zdata) == IS_RESOURCE) { /* Skip these types */ continue; } else { if (formstr->s) { smart_str_appendl(formstr, arg_sep, arg_sep_len); } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); } else { ekey = php_url_encode(prop_name, prop_len); } smart_str_append(formstr, ekey); zend_string_free(ekey); } else { /* Numeric key */ if (num_prefix) { smart_str_appendl(formstr, num_prefix, num_prefix_len); } smart_str_append_long(formstr, idx); } smart_str_appendl(formstr, key_suffix, key_suffix_len); smart_str_appendl(formstr, "=", 1); switch (Z_TYPE_P(zdata)) { case IS_STRING: { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } else { ekey = php_url_encode(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); } smart_str_append(formstr, ekey); zend_string_free(ekey); } break; case IS_LONG: smart_str_append_long(formstr, Z_LVAL_P(zdata)); break; case IS_FALSE: smart_str_appendl(formstr, "0", sizeof("0")-1); break; case IS_TRUE: smart_str_appendl(formstr, "1", sizeof("1")-1); break; case IS_DOUBLE: { char *ekey; size_t ekey_len; ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_P(zdata)); smart_str_appendl(formstr, ekey, ekey_len); efree(ekey); } break; default: { zend_string *ekey; zend_string *tmp; zend_string *str= zval_get_tmp_string(zdata, &tmp); if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(ZSTR_VAL(str), ZSTR_LEN(str)); } else { ekey = php_url_encode(ZSTR_VAL(str), ZSTR_LEN(str)); } smart_str_append(formstr, ekey); zend_tmp_string_release(tmp); zend_string_free(ekey); } } } } ZEND_HASH_FOREACH_END();