Return to http.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard |
1.1 ! misho 1: /* ! 2: +----------------------------------------------------------------------+ ! 3: | PHP Version 5 | ! 4: +----------------------------------------------------------------------+ ! 5: | Copyright (c) 1997-2012 The PHP Group | ! 6: +----------------------------------------------------------------------+ ! 7: | This source file is subject to version 3.01 of the PHP license, | ! 8: | that is bundled with this package in the file LICENSE, and is | ! 9: | available through the world-wide-web at the following url: | ! 10: | http://www.php.net/license/3_01.txt | ! 11: | If you did not receive a copy of the PHP license and are unable to | ! 12: | obtain it through the world-wide-web, please send a note to | ! 13: | license@php.net so we can mail you a copy immediately. | ! 14: +----------------------------------------------------------------------+ ! 15: | Authors: Sara Golemon <pollita@php.net> | ! 16: +----------------------------------------------------------------------+ ! 17: */ ! 18: ! 19: /* $Id: http.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 20: ! 21: #include "php_http.h" ! 22: #include "php_ini.h" ! 23: #include "url.h" ! 24: ! 25: #define URL_DEFAULT_ARG_SEP "&" ! 26: ! 27: /* {{{ php_url_encode_hash */ ! 28: PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, ! 29: const char *num_prefix, int num_prefix_len, ! 30: const char *key_prefix, int key_prefix_len, ! 31: const char *key_suffix, int key_suffix_len, ! 32: zval *type, char *arg_sep TSRMLS_DC) ! 33: { ! 34: char *key = NULL, *ekey, *newprefix, *p; ! 35: int arg_sep_len, key_len, ekey_len, key_type, newprefix_len; ! 36: ulong idx; ! 37: zval **zdata = NULL, *copyzval; ! 38: ! 39: if (!ht) { ! 40: return FAILURE; ! 41: } ! 42: ! 43: if (ht->nApplyCount > 0) { ! 44: /* Prevent recursion */ ! 45: return SUCCESS; ! 46: } ! 47: ! 48: if (!arg_sep) { ! 49: arg_sep = INI_STR("arg_separator.output"); ! 50: if (!arg_sep || !strlen(arg_sep)) { ! 51: arg_sep = URL_DEFAULT_ARG_SEP; ! 52: } ! 53: } ! 54: arg_sep_len = strlen(arg_sep); ! 55: ! 56: for (zend_hash_internal_pointer_reset(ht); ! 57: (key_type = zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, NULL)) != HASH_KEY_NON_EXISTANT; ! 58: zend_hash_move_forward(ht) ! 59: ) { ! 60: if (key_type == HASH_KEY_IS_STRING && key_len && key[key_len-1] == '\0') { ! 61: /* We don't want that trailing NULL */ ! 62: key_len -= 1; ! 63: } ! 64: ! 65: /* handling for private & protected object properties */ ! 66: if (key && *key == '\0' && type != NULL) { ! 67: char *tmp; ! 68: ! 69: zend_object *zobj = zend_objects_get_address(type TSRMLS_CC); ! 70: if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) != SUCCESS) { ! 71: /* private or protected property access outside of the class */ ! 72: continue; ! 73: } ! 74: zend_unmangle_property_name(key, key_len-1, &tmp, &key); ! 75: key_len = strlen(key); ! 76: } ! 77: ! 78: if (zend_hash_get_current_data_ex(ht, (void **)&zdata, NULL) == FAILURE || !zdata || !(*zdata)) { ! 79: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array"); ! 80: return FAILURE; ! 81: } ! 82: if (Z_TYPE_PP(zdata) == IS_ARRAY || Z_TYPE_PP(zdata) == IS_OBJECT) { ! 83: if (key_type == HASH_KEY_IS_STRING) { ! 84: ekey = php_url_encode(key, key_len, &ekey_len); ! 85: newprefix_len = key_suffix_len + ekey_len + key_prefix_len + 3 /* %5B */; ! 86: newprefix = emalloc(newprefix_len + 1); ! 87: p = newprefix; ! 88: ! 89: if (key_prefix) { ! 90: memcpy(p, key_prefix, key_prefix_len); ! 91: p += key_prefix_len; ! 92: } ! 93: ! 94: memcpy(p, ekey, ekey_len); ! 95: p += ekey_len; ! 96: efree(ekey); ! 97: ! 98: if (key_suffix) { ! 99: memcpy(p, key_suffix, key_suffix_len); ! 100: p += key_suffix_len; ! 101: } ! 102: *(p++) = '%'; ! 103: *(p++) = '5'; ! 104: *(p++) = 'B'; ! 105: *p = '\0'; ! 106: } else { ! 107: /* Is an integer key */ ! 108: ekey_len = spprintf(&ekey, 0, "%ld", idx); ! 109: newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */; ! 110: newprefix = emalloc(newprefix_len + 1); ! 111: p = newprefix; ! 112: ! 113: if (key_prefix) { ! 114: memcpy(p, key_prefix, key_prefix_len); ! 115: p += key_prefix_len; ! 116: } ! 117: ! 118: memcpy(p, num_prefix, num_prefix_len); ! 119: p += num_prefix_len; ! 120: ! 121: memcpy(p, ekey, ekey_len); ! 122: p += ekey_len; ! 123: efree(ekey); ! 124: ! 125: if (key_suffix) { ! 126: memcpy(p, key_suffix, key_suffix_len); ! 127: p += key_suffix_len; ! 128: } ! 129: *(p++) = '%'; ! 130: *(p++) = '5'; ! 131: *(p++) = 'B'; ! 132: *p = '\0'; ! 133: } ! 134: ht->nApplyCount++; ! 135: php_url_encode_hash_ex(HASH_OF(*zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_PP(zdata) == IS_OBJECT ? *zdata : NULL), arg_sep TSRMLS_CC); ! 136: ht->nApplyCount--; ! 137: efree(newprefix); ! 138: } else if (Z_TYPE_PP(zdata) == IS_NULL || Z_TYPE_PP(zdata) == IS_RESOURCE) { ! 139: /* Skip these types */ ! 140: continue; ! 141: } else { ! 142: if (formstr->len) { ! 143: smart_str_appendl(formstr, arg_sep, arg_sep_len); ! 144: } ! 145: /* Simple key=value */ ! 146: smart_str_appendl(formstr, key_prefix, key_prefix_len); ! 147: if (key_type == HASH_KEY_IS_STRING) { ! 148: ekey = php_url_encode(key, key_len, &ekey_len); ! 149: smart_str_appendl(formstr, ekey, ekey_len); ! 150: efree(ekey); ! 151: } else { ! 152: /* Numeric key */ ! 153: if (num_prefix) { ! 154: smart_str_appendl(formstr, num_prefix, num_prefix_len); ! 155: } ! 156: ekey_len = spprintf(&ekey, 0, "%ld", idx); ! 157: smart_str_appendl(formstr, ekey, ekey_len); ! 158: efree(ekey); ! 159: } ! 160: smart_str_appendl(formstr, key_suffix, key_suffix_len); ! 161: smart_str_appendl(formstr, "=", 1); ! 162: switch (Z_TYPE_PP(zdata)) { ! 163: case IS_STRING: ! 164: ekey = php_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len); ! 165: break; ! 166: case IS_LONG: ! 167: case IS_BOOL: ! 168: ekey_len = spprintf(&ekey, 0, "%ld", Z_LVAL_PP(zdata)); ! 169: break; ! 170: case IS_DOUBLE: ! 171: ekey_len = spprintf(&ekey, 0, "%.*G", (int) EG(precision), Z_DVAL_PP(zdata)); ! 172: break; ! 173: default: ! 174: /* fall back on convert to string */ ! 175: MAKE_STD_ZVAL(copyzval); ! 176: *copyzval = **zdata; ! 177: zval_copy_ctor(copyzval); ! 178: convert_to_string_ex(©zval); ! 179: ekey = php_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len); ! 180: zval_ptr_dtor(©zval); ! 181: } ! 182: smart_str_appendl(formstr, ekey, ekey_len); ! 183: efree(ekey); ! 184: } ! 185: } ! 186: ! 187: return SUCCESS; ! 188: } ! 189: /* }}} */ ! 190: ! 191: /* {{{ proto string http_build_query(mixed formdata [, string prefix [, string arg_separator]]) ! 192: Generates a form-encoded query string from an associative array or object. */ ! 193: PHP_FUNCTION(http_build_query) ! 194: { ! 195: zval *formdata; ! 196: char *prefix = NULL, *arg_sep=NULL; ! 197: int arg_sep_len = 0, prefix_len = 0; ! 198: smart_str formstr = {0}; ! 199: ! 200: ! 201: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ss", &formdata, &prefix, &prefix_len, &arg_sep, &arg_sep_len) != SUCCESS) { ! 202: RETURN_FALSE; ! 203: } ! 204: ! 205: if (Z_TYPE_P(formdata) != IS_ARRAY && Z_TYPE_P(formdata) != IS_OBJECT) { ! 206: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter 1 expected to be Array or Object. Incorrect value given"); ! 207: RETURN_FALSE; ! 208: } ! 209: ! 210: if (php_url_encode_hash_ex(HASH_OF(formdata), &formstr, prefix, prefix_len, NULL, 0, NULL, 0, (Z_TYPE_P(formdata) == IS_OBJECT ? formdata : NULL), arg_sep TSRMLS_CC) == FAILURE) { ! 211: if (formstr.c) { ! 212: efree(formstr.c); ! 213: } ! 214: RETURN_FALSE; ! 215: } ! 216: ! 217: if (!formstr.c) { ! 218: RETURN_EMPTY_STRING(); ! 219: } ! 220: ! 221: smart_str_0(&formstr); ! 222: ! 223: RETURN_STRINGL(formstr.c, formstr.len, 0); ! 224: } ! 225: /* }}} */ ! 226: ! 227: /* ! 228: * Local variables: ! 229: * tab-width: 4 ! 230: * c-basic-offset: 4 ! 231: * End: ! 232: * vim600: sw=4 ts=4 fdm=marker ! 233: * vim<600: sw=4 ts=4 ! 234: */ ! 235: