X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=src%2Fphp_http_params.c;h=92c144154c8866d4af009ded0ef893eea51ed240;hp=8db5c353bd18c004ecc8bef617431577fafcb526;hb=d5d03014cff8c8ca80ee7866af100d3ceae1bd8f;hpb=54059a470e850eb8380bde2a4ed117e25c1b3e95 diff --git a/src/php_http_params.c b/src/php_http_params.c index 8db5c35..92c1441 100644 --- a/src/php_http_params.c +++ b/src/php_http_params.c @@ -63,24 +63,30 @@ static inline void sanitize_escaped(zval *zv) php_stripcslashes(Z_STR_P(zv)); } -static inline void quote_string(zend_string **zs, zend_bool force) +static inline zend_string *quote_string(zend_string *zs, zend_bool force) { - int len = (*zs)->len; + size_t len = (zs)->len; - *zs = php_addcslashes(*zs, 1, ZEND_STRL("\0..\37\173\\\"")); +#if PHP_VERSION_ID < 70300 + zs = php_addcslashes(zs, 0, ZEND_STRL("\0..\37\173\\\"")); +#else + zs = php_addcslashes(zs, ZEND_STRL("\0..\37\173\\\"")); +#endif - if (force || len != (*zs)->len || strpbrk((*zs)->val, "()<>@,;:\"[]?={} ")) { - int len = (*zs)->len + 2; + if (force || len != (zs)->len || strpbrk((zs)->val, "()<>@,;:\"[]?={} ")) { + int len = (zs)->len + 2; - *zs = zend_string_extend(*zs, len, 0); + zs = zend_string_extend(zs, len, 0); - memmove(&(*zs)->val[1], (*zs)->val, (*zs)->len); - (*zs)->val[0] = '"'; - (*zs)->val[len-1] = '"'; - (*zs)->val[len] = '\0'; + memmove(&(zs)->val[1], (zs)->val, (zs)->len); + (zs)->val[0] = '"'; + (zs)->val[len-1] = '"'; + (zs)->val[len] = '\0'; - zend_string_forget_hash_val(*zs); + zend_string_forget_hash_val(zs); } + + return zs; } /* if (Z_TYPE_P(zv) == IS_STRING) { @@ -109,7 +115,10 @@ static inline void quote_string(zend_string **zs, zend_bool force) static inline void prepare_escaped(zval *zv) { if (Z_TYPE_P(zv) == IS_STRING) { - quote_string(&Z_STR_P(zv), 0); + zend_string *str = quote_string(Z_STR_P(zv), 0); + + zval_dtor(zv); + ZVAL_STR(zv, str); } else { zval_dtor(zv); ZVAL_EMPTY_STRING(zv); @@ -118,7 +127,7 @@ static inline void prepare_escaped(zval *zv) static inline void sanitize_urlencoded(zval *zv) { - Z_STRLEN_P(zv) = php_raw_url_decode(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); + Z_STRLEN_P(zv) = php_url_decode(Z_STRVAL_P(zv), Z_STRLEN_P(zv)); } static inline void prepare_urlencoded(zval *zv) @@ -131,12 +140,11 @@ static inline void prepare_urlencoded(zval *zv) static void sanitize_dimension(zval *zv) { - zval arr, tmp, *cur = NULL; + zval arr, tmp, *cur = &arr; char *var = NULL, *ptr = Z_STRVAL_P(zv), *end = Z_STRVAL_P(zv) + Z_STRLEN_P(zv); long level = 0; array_init(&arr); - cur = &arr; while (ptr < end) { if (!var) { @@ -195,8 +203,8 @@ static void prepare_dimension(php_http_buffer_t *buf, php_http_buffer_t *keybuf, zval *val; php_http_buffer_t prefix; - if (!ZEND_HASH_GET_APPLY_COUNT(ht)) { - ZEND_HASH_INC_APPLY_COUNT(ht); + if (!HT_IS_RECURSIVE(ht)) { + HT_PROTECT_RECURSION(ht); php_http_buffer_init(&prefix); php_http_buffer_append(&prefix, keybuf->data, keybuf->used); @@ -230,7 +238,7 @@ static void prepare_dimension(php_http_buffer_t *buf, php_http_buffer_t *keybuf, php_http_buffer_cut(&prefix, keybuf->used, prefix.used - keybuf->used); } ZEND_HASH_FOREACH_END(); - ZEND_HASH_DEC_APPLY_COUNT(ht); + HT_UNPROTECT_RECURSION(ht); php_http_buffer_dtor(&prefix); } @@ -248,16 +256,18 @@ static inline void sanitize_key(unsigned flags, const char *str, size_t len, zva if (flags & PHP_HTTP_PARAMS_ESCAPED) { sanitize_escaped(zv); } - + if (!Z_STRLEN_P(zv)) { return; } - eos = &Z_STRVAL_P(zv)[Z_STRLEN_P(zv)-1]; - if (*eos == '*') { - *eos = '\0'; - *rfc5987 = 1; - Z_STRLEN_P(zv) -= 1; + if (flags & PHP_HTTP_PARAMS_RFC5987) { + eos = &Z_STRVAL_P(zv)[Z_STRLEN_P(zv)-1]; + if (*eos == '*') { + *eos = '\0'; + *rfc5987 = 1; + Z_STRLEN_P(zv) -= 1; + } } if (flags & PHP_HTTP_PARAMS_URLENCODED) { @@ -487,7 +497,7 @@ static void merge_param(HashTable *params, zval *zdata, zval **current_param, zv zval *test_ptr; while (Z_TYPE_P(zdata_ptr) == IS_ARRAY && (test_ptr = zend_hash_get_current_data(Z_ARRVAL_P(zdata_ptr)))) { - if (Z_TYPE_P(test_ptr) == IS_ARRAY) { + if (Z_TYPE_P(test_ptr) == IS_ARRAY && Z_TYPE_P(ptr) == IS_ARRAY) { zval *tmp_ptr = ptr; /* now find key in ptr */ @@ -552,8 +562,12 @@ static void merge_param(HashTable *params, zval *zdata, zval **current_param, zv static void push_param(HashTable *params, php_http_params_state_t *state, const php_http_params_opts_t *opts) { if (state->val.str) { - if (0 < (state->val.len = state->input.str - state->val.str)) { + if (!state->current.val) { + return; + } else if (0 < (state->val.len = state->input.str - state->val.str)) { sanitize_value(opts->flags, state->val.str, state->val.len, state->current.val, state->rfc5987); + } else { + ZVAL_EMPTY_STRING(state->current.val); } state->rfc5987 = 0; } else if (state->arg.str) { @@ -635,7 +649,7 @@ static size_t check_sep(php_http_params_state_t *state, php_http_params_token_t if (state->quotes || state->escape) { return 0; } - + if (sep) while (*sep) { if (check_str(state->input.str, state->input.len, (*sep)->str, (*sep)->len)) { return (*sep)->len; @@ -685,7 +699,7 @@ HashTable *php_http_params_parse(HashTable *params, const php_http_params_opts_t } else { state.escape = (*state.input.str == '\\'); } - + if (!state.param.str) { /* initialize */ skip_sep(0, &state, opts->param, opts->arg, opts->val); @@ -739,7 +753,7 @@ HashTable *php_http_params_parse(HashTable *params, const php_http_params_opts_t } } } - + if (state.input.len) { ++state.input.str; --state.input.len; @@ -810,13 +824,14 @@ static inline void shift_rfc5988(php_http_buffer_t *buf, char *key_str, size_t k static inline void shift_rfc5988_val(php_http_buffer_t *buf, zval *zv, const char *vss, size_t vsl, unsigned flags) { - zend_string *zs = zval_get_string(zv); - - quote_string(&zs, 1); - php_http_buffer_append(buf, vss, vsl); - php_http_buffer_append(buf, zs->val, zs->len); + zend_string *str, *zs = zval_get_string(zv); + str = quote_string(zs, 1); zend_string_release(zs); + + php_http_buffer_append(buf, vss, vsl); + php_http_buffer_append(buf, str->val, str->len); + zend_string_release(str); } static inline void shift_val(php_http_buffer_t *buf, zval *zvalue, const char *vss, size_t vsl, unsigned flags) @@ -1275,7 +1290,7 @@ PHP_METHOD(HttpParams, offsetSet) } static zend_function_entry php_http_params_methods[] = { - PHP_ME(HttpParams, __construct, ai_HttpParams___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR|ZEND_ACC_FINAL) + PHP_ME(HttpParams, __construct, ai_HttpParams___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(HttpParams, toArray, ai_HttpParams_toArray, ZEND_ACC_PUBLIC) PHP_ME(HttpParams, toString, ai_HttpParams_toString, ZEND_ACC_PUBLIC)