static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, zend_bool is_object TSRMLS_DC) /* {{{ */ { zval **tmp; char *string_key; HashPosition iterator; ulong num_key; uint str_len; int i; for (i = 0; i < indent; i++) { ZEND_PUTS_EX(" "); } ZEND_PUTS_EX("(\n"); indent += PRINT_ZVAL_INDENT; zend_hash_internal_pointer_reset_ex(ht, &iterator); while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) { for (i = 0; i < indent; i++) { ZEND_PUTS_EX(" "); } ZEND_PUTS_EX("["); switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) { case HASH_KEY_IS_STRING: if (is_object) { const char *prop_name, *class_name; int prop_len; int mangled = zend_unmangle_property_name_ex(string_key, str_len - 1, &class_name, &prop_name, &prop_len); ZEND_WRITE_EX(prop_name, prop_len); if (class_name && mangled == SUCCESS) { if (class_name[0]=='*') { ZEND_PUTS_EX(":protected"); } else { ZEND_PUTS_EX(":"); ZEND_PUTS_EX(class_name); ZEND_PUTS_EX(":private"); } } } else { ZEND_WRITE_EX(string_key, str_len-1); } break; case HASH_KEY_IS_LONG: { char key[25]; snprintf(key, sizeof(key), "%ld", num_key); ZEND_PUTS_EX(key); } break; } ZEND_PUTS_EX("] => "); zend_print_zval_r_ex(write_func, *tmp, indent+PRINT_ZVAL_INDENT TSRMLS_CC); ZEND_PUTS_EX("\n"); zend_hash_move_forward_ex(ht, &iterator); } indent -= PRINT_ZVAL_INDENT; for (i = 0; i < indent; i++) { ZEND_PUTS_EX(" "); } ZEND_PUTS_EX(")\n"); }
static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, zend_bool is_object) /* {{{ */ { zval *tmp; zend_string *string_key; zend_ulong num_key; int i; for (i = 0; i < indent; i++) { ZEND_PUTS_EX(" "); } ZEND_PUTS_EX("(\n"); indent += PRINT_ZVAL_INDENT; ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, string_key, tmp) { if (Z_TYPE_P(tmp) == IS_INDIRECT) { tmp = Z_INDIRECT_P(tmp); if (Z_TYPE_P(tmp) == IS_UNDEF) { continue; } } for (i = 0; i < indent; i++) { ZEND_PUTS_EX(" "); } ZEND_PUTS_EX("["); if (string_key) { if (is_object) { const char *prop_name, *class_name; size_t prop_len; int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len); ZEND_WRITE_EX(prop_name, prop_len); if (class_name && mangled == SUCCESS) { if (class_name[0]=='*') { ZEND_PUTS_EX(":protected"); } else { ZEND_PUTS_EX(":"); ZEND_PUTS_EX(class_name); ZEND_PUTS_EX(":private"); } } } else { ZEND_WRITE_EX(ZSTR_VAL(string_key), ZSTR_LEN(string_key)); } } else { char key[25]; snprintf(key, sizeof(key), ZEND_LONG_FMT, num_key); ZEND_PUTS_EX(key); } ZEND_PUTS_EX("] => "); zend_print_zval_r_ex(write_func, tmp, indent+PRINT_ZVAL_INDENT); ZEND_PUTS_EX("\n"); } ZEND_HASH_FOREACH_END(); indent -= PRINT_ZVAL_INDENT; for (i = 0; i < indent; i++) { ZEND_PUTS_EX(" "); } ZEND_PUTS_EX(")\n"); }
static void print_hash(smart_str *buf, HashTable *ht, int indent, zend_bool is_object) /* {{{ */ { zval *tmp; zend_string *string_key; zend_ulong num_key; int i; for (i = 0; i < indent; i++) { smart_str_appendc(buf, ' '); } smart_str_appends(buf, "(\n"); indent += PRINT_ZVAL_INDENT; ZEND_HASH_FOREACH_KEY_VAL_IND(ht, num_key, string_key, tmp) { for (i = 0; i < indent; i++) { smart_str_appendc(buf, ' '); } smart_str_appendc(buf, '['); if (string_key) { if (is_object) { const char *prop_name, *class_name; size_t prop_len; int mangled = zend_unmangle_property_name_ex(string_key, &class_name, &prop_name, &prop_len); smart_str_appendl(buf, prop_name, prop_len); if (class_name && mangled == SUCCESS) { if (class_name[0] == '*') { smart_str_appends(buf, ":protected"); } else { smart_str_appends(buf, ":"); smart_str_appends(buf, class_name); smart_str_appends(buf, ":private"); } } } else { smart_str_append(buf, string_key); } } else { smart_str_append_long(buf, num_key); } smart_str_appends(buf, "] => "); zend_print_zval_r_to_buf(buf, tmp, indent+PRINT_ZVAL_INDENT); smart_str_appends(buf, "\n"); } ZEND_HASH_FOREACH_END(); indent -= PRINT_ZVAL_INDENT; for (i = 0; i < indent; i++) { smart_str_appendc(buf, ' '); } smart_str_appends(buf, ")\n"); }
/* {{{ 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();
/* {{{ 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, copyzval; if (!ht) { return FAILURE; } if (ht->u.v.nApplyCount > 0) { /* 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_IND(ht, idx, key, zdata) { /* handling for private & protected object properties */ if (key) { if (key->val[0] == '\0' && type != NULL) { const char *tmp; zend_object *zobj = Z_OBJ_P(type); if (zend_check_property_access(zobj, key) != SUCCESS) { /* private or protected property access outside of the class */ continue; } zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len); } else { prop_name = key->val; prop_len = key->len; } } 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 + ekey->len + 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, ekey->val, ekey->len); p += ekey->len; 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, "%pd", 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 (ZEND_HASH_APPLY_PROTECTION(ht)) { ht->u.v.nApplyCount++; } 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 (ZEND_HASH_APPLY_PROTECTION(ht)) { ht->u.v.nApplyCount--; } 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; /* fall back on convert to string */ ZVAL_DUP(©zval, zdata); convert_to_string_ex(©zval); if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(Z_STRVAL(copyzval), Z_STRLEN(copyzval)); } else { ekey = php_url_encode(Z_STRVAL(copyzval), Z_STRLEN(copyzval)); } smart_str_append(formstr, ekey); zval_ptr_dtor(©zval); zend_string_free(ekey); } } } } ZEND_HASH_FOREACH_END(); return SUCCESS; }
static zend_always_inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, int objprops) { while (elements-- > 0) { zval key, *data, d, *old_data; zend_ulong idx; ZVAL_UNDEF(&key); if (!php_var_unserialize_internal(&key, p, max, NULL)) { zval_ptr_dtor(&key); return 0; } data = NULL; ZVAL_UNDEF(&d); if (!objprops) { if (Z_TYPE(key) == IS_LONG) { idx = Z_LVAL(key); numeric_key: if (UNEXPECTED((old_data = zend_hash_index_find(ht, idx)) != NULL)) { //??? update hash var_push_dtor(var_hash, old_data); data = zend_hash_index_update(ht, idx, &d); } else { data = zend_hash_index_add_new(ht, idx, &d); } } else if (Z_TYPE(key) == IS_STRING) { if (UNEXPECTED(ZEND_HANDLE_NUMERIC(Z_STR(key), idx))) { goto numeric_key; } if (UNEXPECTED((old_data = zend_hash_find(ht, Z_STR(key))) != NULL)) { //??? update hash var_push_dtor(var_hash, old_data); data = zend_hash_update(ht, Z_STR(key), &d); } else { data = zend_hash_add_new(ht, Z_STR(key), &d); } } else { zval_ptr_dtor(&key); return 0; } } else { if (EXPECTED(Z_TYPE(key) == IS_STRING)) { string_key: { zend_property_info *existing_propinfo; zend_string *new_key, *unmangled; const char *unmangled_class = NULL; const char *unmangled_prop; size_t unmangled_prop_len; if (UNEXPECTED(zend_unmangle_property_name_ex(Z_STR(key), &unmangled_class, &unmangled_prop, &unmangled_prop_len) == FAILURE)) { zval_ptr_dtor(&key); return 0; } unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0); if (Z_TYPE_P(rval) == IS_OBJECT && ((existing_propinfo = zend_hash_find_ptr(&Z_OBJCE_P(rval)->properties_info, unmangled)) != NULL) && (existing_propinfo->flags & ZEND_ACC_PPP_MASK)) { if (existing_propinfo->flags & ZEND_ACC_PROTECTED) { new_key = zend_mangle_property_name( "*", 1, ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS); zend_string_release(unmangled); } else if (existing_propinfo->flags & ZEND_ACC_PRIVATE) { if (unmangled_class != NULL && strcmp(unmangled_class, "*") != 0) { new_key = zend_mangle_property_name( unmangled_class, strlen(unmangled_class), ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS); } else { new_key = zend_mangle_property_name( ZSTR_VAL(existing_propinfo->ce->name), ZSTR_LEN(existing_propinfo->ce->name), ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS); } zend_string_release(unmangled); } else { ZEND_ASSERT(existing_propinfo->flags & ZEND_ACC_PUBLIC); new_key = unmangled; } zend_string_release(Z_STR(key)); ZVAL_STR(&key, new_key); } else { zend_string_release(unmangled); } if ((old_data = zend_hash_find(ht, Z_STR(key))) != NULL) { if (Z_TYPE_P(old_data) == IS_INDIRECT) { old_data = Z_INDIRECT_P(old_data); } var_push_dtor(var_hash, old_data); data = zend_hash_update_ind(ht, Z_STR(key), &d); } else { data = zend_hash_add_new(ht, Z_STR(key), &d); } } } else if (Z_TYPE(key) == IS_LONG) { /* object properties should include no integers */ convert_to_string(&key); goto string_key; } else { zval_ptr_dtor(&key); return 0; } } if (!php_var_unserialize_internal(data, p, max, var_hash)) { zval_ptr_dtor(&key); return 0; } var_push_dtor(var_hash, data); zval_ptr_dtor(&key); if (elements && *(*p-1) != ';' && *(*p-1) != '}') { (*p)--; return 0; } } return 1; }
static inline int msgpack_convert_long_to_properties(HashTable *ht, zval *object, HashTable **properties, HashPosition *prop_pos, uint key_index, zval *val, HashTable *var) /* {{{ */ { zval key_zv; HashTable *props = *properties; if (props != NULL) { zval *data, tplval, *dataval, prop_key_zv; zend_string *prop_key; ulong prop_key_index; const char *class_name, *prop_name; size_t prop_len; for (;; zend_hash_move_forward_ex(props, prop_pos)) { if (zend_hash_get_current_key_ex(props, &prop_key, &prop_key_index, prop_pos) == HASH_KEY_IS_STRING) { zend_unmangle_property_name_ex(prop_key, &class_name, &prop_name, &prop_len); ZVAL_NEW_STR(&prop_key_zv, prop_key); if (var == NULL || !zend_hash_str_exists(var, prop_name, prop_len)) { if ((data = zend_hash_find(ht, prop_key)) != NULL) { switch (Z_TYPE_P(data)) { case IS_ARRAY: { HashTable *dataht; dataht = HASH_OF(val); if ((dataval = zend_hash_index_find(dataht, prop_key_index)) == NULL) { MSGPACK_WARNING("[msgpack] (%s) " "can't get data value by index", __FUNCTION__); return FAILURE; } if (msgpack_convert_array(&tplval, data, dataval) == SUCCESS) { zend_hash_move_forward_ex(props, prop_pos); zend_update_property(Z_OBJCE_P(object), object, prop_name, prop_len, &tplval); return SUCCESS; } return FAILURE; } case IS_OBJECT: { if (msgpack_convert_object(&tplval, data, val) == SUCCESS) { zend_hash_move_forward_ex(props, prop_pos); zend_update_property(Z_OBJCE_P(object), object, prop_name, prop_len, &tplval); return SUCCESS; } return FAILURE; } default: zend_hash_move_forward_ex(props, prop_pos); zend_update_property(Z_OBJCE_P(object), object, prop_name, prop_len, val); return SUCCESS; } } } } else { break; } } *properties = NULL; } ZVAL_LONG(&key_zv, key_index); zend_std_write_property(object, &key_zv, val, NULL); return SUCCESS; }