From d1fb78c1fd8bc565d7f153810015dbd627d46514 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 27 Apr 2015 21:19:50 +0200 Subject: [PATCH] basic support for RFC5988 (Web Linking) --- php_http_params.c | 35 +++++++++++++++++++++++++++++++++-- php_http_params.h | 1 + 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/php_http_params.c b/php_http_params.c index ce785ec..34bc928 100644 --- a/php_http_params.c +++ b/php_http_params.c @@ -541,6 +541,10 @@ static void push_param(HashTable *params, php_http_params_state_t *state, const MAKE_STD_ZVAL(key); ZVAL_NULL(key); + if (opts->flags & PHP_HTTP_PARAMS_RFC5988) { + state->param.str += 1; /* < */ + state->param.len -= 2; /* > */ + } sanitize_key(opts->flags, state->param.str, state->param.len, key, &rfc5987 TSRMLS_CC); state->rfc5987 = rfc5987; if (Z_TYPE_P(key) != IS_STRING) { @@ -623,7 +627,13 @@ HashTable *php_http_params_parse(HashTable *params, const php_http_params_opts_t } while (state.input.len) { - if (*state.input.str == '"' && !state.escape) { + if ((opts->flags & PHP_HTTP_PARAMS_RFC5988) && !state.arg.str) { + if (!state.param.str && *state.input.str == '<') { + state.quotes = 1; + } else if (*state.input.str == '>') { + state.quotes = 0; + } + } else if (*state.input.str == '"' && !state.escape) { state.quotes = !state.quotes; } else { state.escape = (*state.input.str == '\\'); @@ -730,6 +740,22 @@ static inline void shift_rfc5987(php_http_buffer_t *buf, zval *zvalue, const cha } } +static inline void shift_rfc5988(php_http_buffer_t *buf, char *key_str, size_t key_len, const char *ass, size_t asl, unsigned flags TSRMLS_DC) +{ + char *str; + size_t len; + + if (buf->used) { + php_http_buffer_append(buf, ass, asl); + } + + prepare_key(flags, key_str, key_len, &str, &len TSRMLS_CC); + php_http_buffer_appends(buf, "<"); + php_http_buffer_append(buf, str, len); + php_http_buffer_appends(buf, ">"); + efree(str); +} + static inline void shift_val(php_http_buffer_t *buf, zval *zvalue, const char *vss, size_t vsl, unsigned flags TSRMLS_DC) { if (Z_TYPE_P(zvalue) != IS_BOOL) { @@ -789,7 +815,11 @@ static void shift_param(php_http_buffer_t *buf, char *key_str, size_t key_len, z shift_arg(buf, key_str, key_len, zvalue, ass, asl, vss, vsl, flags TSRMLS_CC); } } else { - shift_key(buf, key_str, key_len, pss, psl, flags TSRMLS_CC); + if (flags & PHP_HTTP_PARAMS_RFC5988) { + shift_rfc5988(buf, key_str, key_len, pss, psl, flags TSRMLS_CC); + } else { + shift_key(buf, key_str, key_len, pss, psl, flags TSRMLS_CC); + } shift_val(buf, zvalue, vss, vsl, flags TSRMLS_CC); } } @@ -1180,6 +1210,7 @@ PHP_MINIT_FUNCTION(http_params) zend_declare_class_constant_long(php_http_params_class_entry, ZEND_STRL("PARSE_URLENCODED"), PHP_HTTP_PARAMS_URLENCODED TSRMLS_CC); zend_declare_class_constant_long(php_http_params_class_entry, ZEND_STRL("PARSE_DIMENSION"), PHP_HTTP_PARAMS_DIMENSION TSRMLS_CC); zend_declare_class_constant_long(php_http_params_class_entry, ZEND_STRL("PARSE_RFC5987"), PHP_HTTP_PARAMS_RFC5987 TSRMLS_CC); + zend_declare_class_constant_long(php_http_params_class_entry, ZEND_STRL("PARSE_RFC5988"), PHP_HTTP_PARAMS_RFC5988 TSRMLS_CC); zend_declare_class_constant_long(php_http_params_class_entry, ZEND_STRL("PARSE_DEFAULT"), PHP_HTTP_PARAMS_DEFAULT TSRMLS_CC); zend_declare_class_constant_long(php_http_params_class_entry, ZEND_STRL("PARSE_QUERY"), PHP_HTTP_PARAMS_QUERY TSRMLS_CC); diff --git a/php_http_params.h b/php_http_params.h index 42f56f9..e1ebe27 100644 --- a/php_http_params.h +++ b/php_http_params.h @@ -23,6 +23,7 @@ typedef struct php_http_params_token { #define PHP_HTTP_PARAMS_URLENCODED 0x04 #define PHP_HTTP_PARAMS_DIMENSION 0x08 #define PHP_HTTP_PARAMS_RFC5987 0x10 +#define PHP_HTTP_PARAMS_RFC5988 0x20 #define PHP_HTTP_PARAMS_QUERY (PHP_HTTP_PARAMS_URLENCODED|PHP_HTTP_PARAMS_DIMENSION) #define PHP_HTTP_PARAMS_DEFAULT (PHP_HTTP_PARAMS_ESCAPED|PHP_HTTP_PARAMS_RFC5987) -- 2.30.2