static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements, int objprops) { while (elements-- > 0) { zval *key, *data, **old_data; ALLOC_INIT_ZVAL(key); if (!php_var_unserialize2(&key, p, max, NULL TSRMLS_CC)) { zval_dtor(key); FREE_ZVAL(key); return 0; } if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) { zval_dtor(key); FREE_ZVAL(key); return 0; } ALLOC_INIT_ZVAL(data); if (!php_var_unserialize2(&data, p, max, var_hash TSRMLS_CC)) { zval_dtor(key); FREE_ZVAL(key); zval_dtor(data); FREE_ZVAL(data); return 0; } switch (Z_TYPE_P(key)) { case IS_LONG: if (objprops) { /* show a warning for not compatible */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "got integer prop. %d", Z_LVAL_P(key)); } if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) { var_push_dtor(var_hash, old_data); } zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL); break; case IS_STRING: if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) { var_push_dtor(var_hash, old_data); } zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL); break; } zval_dtor(key); FREE_ZVAL(key); if (elements && *(*p-1) != ';' && *(*p-1) != '}') { (*p)--; return 0; } } return 1; }
static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements, int objprops) { while (elements-- > 0) { zval *key, *data, **old_data; ALLOC_INIT_ZVAL(key); if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) { var_push_dtor_no_addref(var_hash, &key); return 0; } if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) { var_push_dtor_no_addref(var_hash, &key); return 0; } ALLOC_INIT_ZVAL(data); if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) { var_push_dtor_no_addref(var_hash, &key); var_push_dtor_no_addref(var_hash, &data); return 0; } if (!objprops) { switch (Z_TYPE_P(key)) { case IS_LONG: if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) { var_push_dtor(var_hash, old_data); } zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL); break; case IS_STRING: if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) { var_push_dtor(var_hash, old_data); } zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL); break; } } else { /* object properties should include no integers */ convert_to_string(key); if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) { var_push_dtor(var_hash, old_data); } zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof data, NULL); } var_push_dtor(var_hash, &data); var_push_dtor_no_addref(var_hash, &key); if (elements && *(*p-1) != ';' && *(*p-1) != '}') { (*p)--; return 0; } } return 1; }
static void php_xml2array_get_properties (xmlNodePtr cur_node, zval * nodes, char *name) { if (cur_node->properties) { xmlAttrPtr attr = NULL; zval **tmp; if (zend_symtable_find(Z_ARRVAL_P(nodes), name, strlen(name) + 1, (void**)&tmp) == FAILURE) { return;//this should not happen } zval *target = *tmp; if (Z_TYPE_PP(tmp) != IS_ARRAY) { zval *value_zval = init_zval_array(); target = value_zval; zval *copy; MAKE_STD_ZVAL(copy); MAKE_COPY_ZVAL(tmp, copy); add_assoc_zval(value_zval, "value", copy); zend_symtable_update(Z_ARRVAL_P(nodes), name, strlen(name)+1, (void *) &value_zval, sizeof(zval *), NULL); } for(attr = cur_node->properties; NULL != attr; attr = attr->next) { xmlChar * prop = NULL; prop = xmlGetProp(cur_node, attr->name); char *attr_name = (char*)attr->name; zval *attr_zval; MAKE_STD_ZVAL(attr_zval); ZVAL_STRING(attr_zval, prop, 1); zend_symtable_update(Z_ARRVAL_P(target), attr_name, strlen(attr_name)+1, (void *) &attr_zval, sizeof(zval *), NULL); xmlFree(prop); } } }
/** * @brief Fetches @a index if it exists from the array @a arr * @param[out] fetched <code>&$arr[$index]</code>; @a fetched is modified only when the function returns 1 * @param arr Array * @param index Index * @return isset($arr[$index]) * @retval 0 Not exists, @a arr is not an array or @a index is of not supported type * @retval 1 Exists * @note @c index will be handled as follows: @c NULL is treated as an empty string, @c double values are cast to @c integer, @c bool or @c resource are treated as @c integer * @note $arr[$index] is returned as is: no copying occurs, reference copunt is not updated * @throw E_WARNING if @a offset is not a scalar */ int zephir_array_isset_fetch(zval **fetched, const zval *arr, zval *index, int readonly TSRMLS_DC) { HashTable *h; zval **val; int result; if (Z_TYPE_P(arr) != IS_ARRAY) { *fetched = ZEPHIR_GLOBAL(global_null); if (!readonly) { Z_ADDREF_P(*fetched); } return 0; } h = Z_ARRVAL_P(arr); switch (Z_TYPE_P(index)) { case IS_NULL: result = zephir_hash_find(h, SS(""), (void**)&val); break; case IS_DOUBLE: result = zend_hash_index_find(h, (ulong)Z_DVAL_P(index), (void**)&val); break; case IS_LONG: case IS_BOOL: case IS_RESOURCE: result = zend_hash_index_find(h, Z_LVAL_P(index), (void**)&val); break; case IS_STRING: result = zend_symtable_find(h, (Z_STRLEN_P(index) ? Z_STRVAL_P(index) : ""), Z_STRLEN_P(index)+1, (void**)&val); break; default: zend_error(E_WARNING, "Illegal offset type"); *fetched = ZEPHIR_GLOBAL(global_null); if (!readonly) { Z_ADDREF_P(*fetched); } return 0; } if (result == SUCCESS) { *fetched = *val; if (!readonly) { Z_ADDREF_P(*fetched); } return 1; } *fetched = ZEPHIR_GLOBAL(global_null); if (!readonly) { Z_ADDREF_P(*fetched); } return 0; }
/** * @ret 父亲zval * @name 父亲name * @r 子zval * @son_name 子name */ static void php_xml2array_add_val (zval *ret, const xmlChar *name, zval *r, char *son_key) { zval **tmp = NULL; char *key = (char *)name;//要插入的node 的key int has_tmp = zend_symtable_find(Z_ARRVAL(*ret), key, strlen(key) + 1, (void**)&tmp); if (has_tmp == SUCCESS && tmp != NULL && Z_TYPE_PP(tmp) == IS_ARRAY && son_key == NULL && Z_TYPE_P(r) == IS_STRING) {//avoid <xx></xx>,<xx></xx> zval_ptr_dtor(&r); return; } if(son_key != NULL && zend_symtable_find(Z_ARRVAL(*ret), key, strlen(key) + 1, (void**)&tmp) != FAILURE && Z_TYPE_PP(tmp) == IS_ARRAY) { zval **son_val = NULL; zend_symtable_find(Z_ARRVAL_P(r), son_key , strlen(son_key)+1, (void**)&son_val); zval *son_val_copy; MAKE_STD_ZVAL(son_val_copy); MAKE_COPY_ZVAL(son_val, son_val_copy); zval **tmp_val = NULL; if (zend_symtable_find(Z_ARRVAL_P(*tmp), son_key , strlen(son_key)+1, (void**)&tmp_val) != FAILURE) {//已经包含同名子元素 if (Z_TYPE_PP(tmp_val) == IS_ARRAY && zend_hash_index_exists(Z_ARRVAL_PP(tmp_val), 0)) { add_next_index_zval(*tmp_val, son_val_copy); } else { zval *son_arr = init_zval_array(); zval *copy; MAKE_STD_ZVAL(copy); MAKE_COPY_ZVAL(tmp_val, copy); add_next_index_zval(son_arr, copy); add_next_index_zval(son_arr, son_val_copy); zend_symtable_update(Z_ARRVAL_PP(tmp), son_key, strlen(son_key)+1, (void *) &son_arr, sizeof(zval *), NULL); } } else { add_assoc_zval(*tmp, son_key, son_val_copy); } zval_ptr_dtor(&r);//accept a zval** param } else { add_assoc_zval(ret, key, r); } }
static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, int objprops) { while (elements-- > 0) { zval key, *data, d, *old_data; ZVAL_UNDEF(&key); if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) { zval_dtor(&key); return 0; } if (Z_TYPE(key) != IS_LONG && Z_TYPE(key) != IS_STRING) { zval_dtor(&key); return 0; } data = NULL; ZVAL_UNDEF(&d); if (!objprops) { switch (Z_TYPE(key)) { case IS_LONG: if ((old_data = zend_hash_index_find(ht, Z_LVAL(key))) != NULL) { //??? update hash var_push_dtor(var_hash, old_data); } data = zend_hash_index_update(ht, Z_LVAL(key), &d); break; case IS_STRING: if ((old_data = zend_symtable_find(ht, Z_STR(key))) != NULL) { //??? update hash var_push_dtor(var_hash, old_data); } data = zend_symtable_update(ht, Z_STR(key), &d); break; } } else { /* object properties should include no integers */ convert_to_string(&key); //??? #if 1 data = zend_hash_update_ind(ht, Z_STR(key), &d); #else if ((data = zend_hash_find(ht, Z_STR(key))) != NULL) { if (Z_TYPE_P(data) == IS_INDIRECT) { data = Z_INDIRECT_P(data); } zval_ptr_dtor(data); //??? var_push_dtor(var_hash, data); ZVAL_UNDEF(data); } else { data = zend_hash_update(ht, Z_STR(key), &d); } #endif } zval_dtor(&key); if (!php_var_unserialize(data, p, max, var_hash TSRMLS_CC)) { return 0; } if (elements && *(*p-1) != ';' && *(*p-1) != '}') { (*p)--; return 0; } } return 1; }
/** * @brief Reads an item from @a arr at position @a index and stores it to @a return_value * @param return_value[out] Return value * @param arr Array * @param index Index * @param silent 0 to suppress all warnings, @c PH_NOISY to enable * @return Whether the operation succeeded * @retval @c FAILURE Failure, @a arr is not an array * @retval @c SUCCESS Success * @throw @c E_WARNING if @c arr is not an array and @c silent = @c PH_NOISY * @throw @c E_WARNING if @c index is not of the supported type and @c silent = @c PH_NOISY * @throw @c E_NOTICE if @c index does not exist and @c silent = @c PH_NOISY * @warning @c *return_value should be either @c NULL (preferred) or point to not initialized memory; if @c *return_value points to a valid variable, mmemory leak is possible * @note @c index will be handled as follows: @c NULL is treated as an empty string, @c double values are cast to @c integer, @c bool or @c resource are treated as @c integer */ int zephir_array_fetch(zval **return_value, zval *arr, zval *index, int flags ZEPHIR_DEBUG_PARAMS TSRMLS_DC) { zval **zv; HashTable *ht; int result; ulong uidx = 0; char *sidx = NULL; if (Z_TYPE_P(arr) == IS_ARRAY) { ht = Z_ARRVAL_P(arr); switch (Z_TYPE_P(index)) { case IS_NULL: result = zephir_hash_find(ht, SS(""), (void**) &zv); sidx = ""; break; case IS_DOUBLE: uidx = (ulong)Z_DVAL_P(index); result = zend_hash_index_find(ht, uidx, (void**) &zv); break; case IS_LONG: case IS_BOOL: case IS_RESOURCE: uidx = Z_LVAL_P(index); result = zend_hash_index_find(ht, uidx, (void**) &zv); break; case IS_STRING: sidx = Z_STRLEN_P(index) ? Z_STRVAL_P(index) : ""; result = zend_symtable_find(ht, Z_STRVAL_P(index), Z_STRLEN_P(index)+1, (void**) &zv); break; default: if ((flags & PH_NOISY) == PH_NOISY) { zend_error(E_WARNING, "Illegal offset type in %s on line %d", file, line); } result = FAILURE; break; } if (result != FAILURE) { *return_value = *zv; if ((flags & PH_READONLY) != PH_READONLY) { Z_ADDREF_PP(return_value); } return SUCCESS; } if ((flags & PH_NOISY) == PH_NOISY) { if (sidx == NULL) { zend_error(E_NOTICE, "Undefined index: %ld in %s on line %d", uidx, file, line); } else { zend_error(E_NOTICE, "Undefined index: %s in %s on line %d", sidx, file, line); } } } *return_value = ZEPHIR_GLOBAL(global_null); if ((flags & PH_READONLY) != PH_READONLY) { Z_ADDREF_PP(return_value); } return FAILURE; }