Skip to content

Commit b374b41

Browse files
author
Rui Hirokawa
committed
added an option to http_build_query for RFC-3986
based url-encoding.
1 parent f3a4bfe commit b374b41

File tree

4 files changed

+33
-11
lines changed

4 files changed

+33
-11
lines changed

Diff for: ext/standard/basic_functions.c

+3
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_http_build_query, 0, 0, 1)
15131513
ZEND_ARG_INFO(0, formdata)
15141514
ZEND_ARG_INFO(0, prefix)
15151515
ZEND_ARG_INFO(0, arg_separator)
1516+
ZEND_ARG_INFO(0, enc_type)
15161517
ZEND_END_ARG_INFO()
15171518
/* }}} */
15181519
/* {{{ image.c */
@@ -3531,6 +3532,8 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
35313532
REGISTER_LONG_CONSTANT("PHP_URL_PATH", PHP_URL_PATH, CONST_CS | CONST_PERSISTENT);
35323533
REGISTER_LONG_CONSTANT("PHP_URL_QUERY", PHP_URL_QUERY, CONST_CS | CONST_PERSISTENT);
35333534
REGISTER_LONG_CONSTANT("PHP_URL_FRAGMENT", PHP_URL_FRAGMENT, CONST_CS | CONST_PERSISTENT);
3535+
REGISTER_LONG_CONSTANT("PHP_QUERY_RFC1738", PHP_QUERY_RFC1738, CONST_CS | CONST_PERSISTENT);
3536+
REGISTER_LONG_CONSTANT("PHP_QUERY_RFC3986", PHP_QUERY_RFC3986, CONST_CS | CONST_PERSISTENT);
35343537

35353538
#define REGISTER_MATH_CONSTANT(x) REGISTER_DOUBLE_CONSTANT(#x, x, CONST_CS | CONST_PERSISTENT)
35363539
REGISTER_MATH_CONSTANT(M_E);

Diff for: ext/standard/http.c

+26-10
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
2929
const char *num_prefix, int num_prefix_len,
3030
const char *key_prefix, int key_prefix_len,
3131
const char *key_suffix, int key_suffix_len,
32-
zval *type, char *arg_sep TSRMLS_DC)
32+
zval *type, char *arg_sep, int enc_type TSRMLS_DC)
3333
{
3434
char *key = NULL, *ekey, *newprefix, *p;
3535
int arg_sep_len, key_len, ekey_len, key_type, newprefix_len;
@@ -81,7 +81,11 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
8181
}
8282
if (Z_TYPE_PP(zdata) == IS_ARRAY || Z_TYPE_PP(zdata) == IS_OBJECT) {
8383
if (key_type == HASH_KEY_IS_STRING) {
84-
ekey = php_url_encode(key, key_len, &ekey_len);
84+
if (enc_type == PHP_QUERY_RFC3986) {
85+
ekey = php_raw_url_encode(key, key_len, &ekey_len);
86+
} else {
87+
ekey = php_url_encode(key, key_len, &ekey_len);
88+
}
8589
newprefix_len = key_suffix_len + ekey_len + key_prefix_len + 3 /* %5B */;
8690
newprefix = emalloc(newprefix_len + 1);
8791
p = newprefix;
@@ -132,7 +136,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
132136
*p = '\0';
133137
}
134138
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);
139+
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, enc_type TSRMLS_CC);
136140
ht->nApplyCount--;
137141
efree(newprefix);
138142
} else if (Z_TYPE_PP(zdata) == IS_NULL || Z_TYPE_PP(zdata) == IS_RESOURCE) {
@@ -145,7 +149,11 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
145149
/* Simple key=value */
146150
smart_str_appendl(formstr, key_prefix, key_prefix_len);
147151
if (key_type == HASH_KEY_IS_STRING) {
148-
ekey = php_url_encode(key, key_len, &ekey_len);
152+
if (enc_type == PHP_QUERY_RFC3986) {
153+
ekey = php_raw_url_encode(key, key_len, &ekey_len);
154+
} else {
155+
ekey = php_url_encode(key, key_len, &ekey_len);
156+
}
149157
smart_str_appendl(formstr, ekey, ekey_len);
150158
efree(ekey);
151159
} else {
@@ -161,7 +169,11 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
161169
smart_str_appendl(formstr, "=", 1);
162170
switch (Z_TYPE_PP(zdata)) {
163171
case IS_STRING:
164-
ekey = php_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len);
172+
if (enc_type == PHP_QUERY_RFC3986) {
173+
ekey = php_raw_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len);
174+
} else {
175+
ekey = php_url_encode(Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata), &ekey_len);
176+
}
165177
break;
166178
case IS_LONG:
167179
case IS_BOOL:
@@ -176,7 +188,11 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
176188
*copyzval = **zdata;
177189
zval_copy_ctor(copyzval);
178190
convert_to_string_ex(&copyzval);
179-
ekey = php_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len);
191+
if (enc_type == PHP_QUERY_RFC3986) {
192+
ekey = php_raw_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len);
193+
} else {
194+
ekey = php_url_encode(Z_STRVAL_P(copyzval), Z_STRLEN_P(copyzval), &ekey_len);
195+
}
180196
zval_ptr_dtor(&copyzval);
181197
}
182198
smart_str_appendl(formstr, ekey, ekey_len);
@@ -188,17 +204,17 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
188204
}
189205
/* }}} */
190206

191-
/* {{{ proto string http_build_query(mixed formdata [, string prefix [, string arg_separator]])
207+
/* {{{ proto string http_build_query(mixed formdata [, string prefix [, string arg_separator [, int enc_type]]])
192208
Generates a form-encoded query string from an associative array or object. */
193209
PHP_FUNCTION(http_build_query)
194210
{
195211
zval *formdata;
196212
char *prefix = NULL, *arg_sep=NULL;
197213
int arg_sep_len = 0, prefix_len = 0;
198214
smart_str formstr = {0};
199-
215+
long enc_type = PHP_QUERY_RFC1738;
200216

201-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ss", &formdata, &prefix, &prefix_len, &arg_sep, &arg_sep_len) != SUCCESS) {
217+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ssl", &formdata, &prefix, &prefix_len, &arg_sep, &arg_sep_len, &enc_type) != SUCCESS) {
202218
RETURN_FALSE;
203219
}
204220

@@ -207,7 +223,7 @@ PHP_FUNCTION(http_build_query)
207223
RETURN_FALSE;
208224
}
209225

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) {
226+
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, enc_type TSRMLS_CC) == FAILURE) {
211227
if (formstr.c) {
212228
efree(formstr.c);
213229
}

Diff for: ext/standard/php_http.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
2828
const char *num_prefix, int num_prefix_len,
2929
const char *key_prefix, int key_prefix_len,
3030
const char *key_suffix, int key_suffix_len,
31-
zval *type, char *arg_sep TSRMLS_DC);
31+
zval *type, char *arg_sep, int enc_type TSRMLS_DC);
3232
#define php_url_encode_hash(ht, formstr) php_url_encode_hash_ex((ht), (formstr), NULL, 0, NULL, 0, NULL, 0, NULL TSRMLS_CC)
3333

3434
PHP_FUNCTION(http_build_query);

Diff for: ext/standard/url.h

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ PHP_FUNCTION(get_headers);
5555
#define PHP_URL_QUERY 6
5656
#define PHP_URL_FRAGMENT 7
5757

58+
#define PHP_QUERY_RFC1738 1
59+
#define PHP_QUERY_RFC3986 2
60+
5861
#endif /* URL_H */
5962

6063
/*

0 commit comments

Comments
 (0)