| modification, are permitted provided that the conditions mentioned |
| in the accompanying LICENSE file are met. |
+--------------------------------------------------------------------+
- | Copyright (c) 2004-2006, Michael Wallner <mike@php.net> |
+ | Copyright (c) 2004-2007, Michael Wallner <mike@php.net> |
+--------------------------------------------------------------------+
*/
#include "php_http.h"
#include "php_variables.h"
-#ifdef HAVE_ICONV
+#ifdef HTTP_HAVE_ICONV
# undef PHP_ATOM_INC
# include "ext/iconv/php_iconv.h"
# include "ext/standard/url.h"
#include "php_http_querystring_api.h"
#ifdef ZEND_ENGINE_2
-#define OBJ_PROP_CE http_querystring_object_ce
+#define THIS_CE http_querystring_object_ce
extern zend_class_entry *http_querystring_object_ce;
#endif
-#ifdef HAVE_ICONV
+
+#define http_querystring_modify_array_ex(q, t, k, kl, i, pe) _http_querystring_modify_array_ex((q), (t), (k), (kl), (i), (pe) TSRMLS_CC)
+static inline int _http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC);
+#define http_querystring_modify_array(q, p) _http_querystring_modify_array((q), (p) TSRMLS_CC)
+static inline int _http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC);
+
+
+#ifdef HTTP_HAVE_ICONV
PHP_HTTP_API int _http_querystring_xlate(zval *array, zval *param, const char *ie, const char *oe TSRMLS_DC)
{
HashPosition pos;
zval **entry = NULL;
- char *xlate_str = NULL, *xkey, *kstr = NULL;
+ char *xlate_str = NULL, *xkey;
size_t xlate_len = 0, xlen;
- uint klen = 0;
- ulong kidx = 0;
+ HashKey key = initHashKey(0);
- FOREACH_KEYLENVAL(pos, param, kstr, klen, kidx, entry) {
- if (kstr) {
- if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(kstr, klen-1, &xkey, &xlen, oe, ie)) {
- http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", klen-1, kstr, ie, oe);
+ FOREACH_KEYVAL(pos, param, key, entry) {
+ if (key.type == HASH_KEY_IS_STRING) {
+ if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(key.str, key.len-1, &xkey, &xlen, oe, ie)) {
+ http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", key.len-1, key.str, ie, oe);
return FAILURE;
}
}
if (Z_TYPE_PP(entry) == IS_STRING) {
if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
- if (kstr) {
+ if (key.type == HASH_KEY_IS_STRING) {
efree(xkey);
}
http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry), Z_STRVAL_PP(entry), ie, oe);
return FAILURE;
}
- if (kstr) {
+ if (key.type == HASH_KEY_IS_STRING) {
add_assoc_stringl_ex(array, xkey, xlen+1, xlate_str, xlate_len, 0);
} else {
- add_index_stringl(array, kidx, xlate_str, xlate_len, 0);
+ add_index_stringl(array, key.num, xlate_str, xlate_len, 0);
}
} else if (Z_TYPE_PP(entry) == IS_ARRAY) {
zval *subarray;
MAKE_STD_ZVAL(subarray);
array_init(subarray);
- if (kstr) {
+ if (key.type == HASH_KEY_IS_STRING) {
add_assoc_zval_ex(array, xkey, xlen+1, subarray);
} else {
- add_index_zval(array, kidx, subarray);
+ add_index_zval(array, key.num, subarray);
}
if (SUCCESS != http_querystring_xlate(subarray, *entry, ie, oe)) {
- if (kstr) {
+ if (key.type == HASH_KEY_IS_STRING) {
efree(xkey);
}
return FAILURE;
}
}
- if (kstr) {
- kstr = NULL;
+ if (key.type == HASH_KEY_IS_STRING) {
efree(xkey);
}
}
}
}
-PHP_HTTP_API int _http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC)
+PHP_HTTP_API int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC)
+{
+ if (Z_TYPE_P(params) == IS_ARRAY) {
+ return http_querystring_modify_array(qarray, params);
+ } else if (Z_TYPE_P(params) == IS_OBJECT) {
+#ifdef ZEND_ENGINE_2
+ if (instanceof_function(Z_OBJCE_P(params), http_querystring_object_ce TSRMLS_CC)) {
+ return http_querystring_modify_array(qarray, zend_read_property(THIS_CE, params, ZEND_STRS("queryArray")-1, 0 TSRMLS_CC));
+ } else {
+#endif
+ return http_querystring_modify_array(qarray, params);
+#ifdef ZEND_ENGINE_2
+ }
+#endif
+ } else {
+ int rv;
+ zval array;
+
+ INIT_PZVAL(&array);
+ array_init(&array);
+
+ ZVAL_ADDREF(params);
+ convert_to_string_ex(¶ms);
+ sapi_module.treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(params)), &array TSRMLS_CC);
+ zval_ptr_dtor(¶ms);
+ rv = http_querystring_modify_array(qarray, &array);
+ zval_dtor(&array);
+ return rv;
+ }
+}
+
+static inline int _http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC)
+{
+ int rv = 0;
+ HashKey key = initHashKey(0);
+ HashPosition pos;
+ zval **params_entry = NULL;
+
+ FOREACH_HASH_KEYVAL(pos, HASH_OF(params), key, params_entry) {
+ /* only public properties */
+ if ((key.type != HASH_KEY_IS_STRING || *key.str) && http_querystring_modify_array_ex(qarray, key.type, key.str, key.len, key.num, *params_entry)) {
+ rv = 1;
+ }
+ }
+
+ return rv;
+}
+
+static inline int _http_querystring_modify_array_ex(zval *qarray, int key_type, char *key, int keylen, ulong idx, zval *params_entry TSRMLS_DC)
{
zval **qarray_entry;
zval equal;
/* recursive */
- if (Z_TYPE_P(params_entry) == IS_ARRAY) {
- return http_querystring_modify_array(*qarray_entry, params_entry);
+ if (Z_TYPE_P(params_entry) == IS_ARRAY || Z_TYPE_P(params_entry) == IS_OBJECT) {
+ return http_querystring_modify(*qarray_entry, params_entry);
}
/* equal */
if ((SUCCESS == is_equal_function(&equal, *qarray_entry, params_entry TSRMLS_CC)) && Z_BVAL(equal)) {
}
/* add */
- ZVAL_ADDREF(params_entry);
+ if (Z_TYPE_P(params_entry) == IS_OBJECT) {
+ zval *new_array;
+
+ MAKE_STD_ZVAL(new_array);
+ array_init(new_array);
+ http_querystring_modify_array(new_array, params_entry);
+ params_entry = new_array;
+ } else {
+ ZVAL_ADDREF(params_entry);
+ }
if (key_type == HASH_KEY_IS_STRING) {
add_assoc_zval_ex(qarray, key, keylen, params_entry);
} else {
return 1;
}
-PHP_HTTP_API int _http_querystring_modify_array(zval *qarray, zval *params TSRMLS_DC)
-{
- int rv = 0;
- char *key = NULL;
- uint keylen = 0;
- ulong idx = 0;
- HashPosition pos;
- zval **params_entry = NULL;
-
- FOREACH_KEYLENVAL(pos, params, key, keylen, idx, params_entry) {
- if (http_querystring_modify_array_ex(qarray, key ? HASH_KEY_IS_STRING : HASH_KEY_IS_LONG, key, keylen, idx, *params_entry)) {
- rv = 1;
- }
- key = NULL;
- }
-
- return rv;
-}
-
-PHP_HTTP_API int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC)
-{
- if (Z_TYPE_P(params) == IS_ARRAY) {
- return http_querystring_modify_array(qarray, params);
- } else if (Z_TYPE_P(params) == IS_OBJECT) {
-#ifdef ZEND_ENGINE_2
- if (!instanceof_function(Z_OBJCE_P(params), http_querystring_object_ce TSRMLS_CC)) {
-#endif
- zval temp_array;
- INIT_ZARR(temp_array, HASH_OF(params));
- return http_querystring_modify_array(qarray, &temp_array);
-#ifdef ZEND_ENGINE_2
- }
- return http_querystring_modify_array(qarray, GET_PROP_EX(params, queryArray));
-#endif
- } else {
- int rv;
- zval array;
-
- INIT_PZVAL(&array);
- array_init(&array);
-
- ZVAL_ADDREF(params);
- convert_to_string_ex(¶ms);
- sapi_module.treat_data(PARSE_STRING, estrdup(Z_STRVAL_P(params)), &array TSRMLS_CC);
- zval_ptr_dtor(¶ms);
- rv = http_querystring_modify_array(qarray, &array);
- zval_dtor(&array);
- return rv;
- }
-}
-
/*
* Local variables:
* tab-width: 4