From 6dec39305b19e86425d30d10bff7fa788d3d83ab Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 14 Dec 2012 13:42:48 +0000 Subject: [PATCH] simple escape/quotes support for the params parser --- php_http_params.c | 26 +++++++++++++++----------- phpunit/HeaderTest.php | 10 +++++----- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/php_http_params.c b/php_http_params.c index d669f25..43447d9 100644 --- a/php_http_params.c +++ b/php_http_params.c @@ -45,6 +45,8 @@ typedef struct php_http_params_state { zval **args; zval **val; } current; + unsigned quotes:1; + unsigned escape:1; } php_http_params_state_t; static inline void sanitize_default(zval *zv TSRMLS_DC) @@ -421,12 +423,7 @@ static void push_param(HashTable *params, php_http_params_state_t *state, const MAKE_STD_ZVAL(val); if (opts->defval) { -#if PHP_VERSION_ID >= 50400 ZVAL_COPY_VALUE(val, opts->defval); -#else - val->value = opts->defval->value; - Z_TYPE_P(val) = Z_TYPE_P(opts->defval); -#endif zval_copy_ctor(val); } else { ZVAL_TRUE(val); @@ -452,6 +449,10 @@ static size_t check_sep(php_http_params_state_t *state, php_http_params_token_t { php_http_params_token_t **sep = separators; + 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; @@ -479,7 +480,7 @@ static void skip_sep(size_t skip, php_http_params_state_t *state, php_http_param PHP_HTTP_API HashTable *php_http_params_parse(HashTable *params, const php_http_params_opts_t *opts TSRMLS_DC) { - php_http_params_state_t state = {{NULL,0}, {NULL,0}, {NULL,0}, {NULL,0}, {NULL,NULL,NULL}}; + php_http_params_state_t state = {{NULL,0}, {NULL,0}, {NULL,0}, {NULL,0}, {NULL,NULL,NULL}, 0, 0}; state.input.str = opts->input.str; state.input.len = opts->input.len; @@ -490,10 +491,13 @@ PHP_HTTP_API HashTable *php_http_params_parse(HashTable *params, const php_http_ } while (state.input.len) { - if (*state.input.str == '\\') { - ++state.input.str; - --state.input.len; - } else if (!state.param.str) { + if (*state.input.str == '"' && !state.escape) { + state.quotes = !state.quotes; + } else { + state.escape = (*state.input.str == '\\'); + } + + if (!state.param.str) { /* initialize */ skip_sep(0, &state, opts->param, opts->arg, opts->val TSRMLS_CC); state.param.str = state.input.str; @@ -546,7 +550,7 @@ PHP_HTTP_API HashTable *php_http_params_parse(HashTable *params, const php_http_ } } } - + if (state.input.len) { ++state.input.str; --state.input.len; diff --git a/phpunit/HeaderTest.php b/phpunit/HeaderTest.php index c04a7f7..184f21a 100644 --- a/phpunit/HeaderTest.php +++ b/phpunit/HeaderTest.php @@ -47,9 +47,9 @@ class HeaderTest extends PHPUnit_Framework_TestCase { function testParse() { $header = "Foo: bar\nBar: foo\n"; $this->assertEquals(array("Foo"=>"bar","Bar"=>"foo"), http\Header::parse($header)); - $header = http\Header::parse($header, "http\\Header"); - $this->assertCount(2, $header); - $this->assertContainsOnlyInstancesOf("http\\Header", $header); + $headers = http\Header::parse($header, "http\\Header"); + $this->assertCount(2, $headers); + $this->assertContainsOnlyInstancesOf("http\\Header", $headers); } function testParseError() { @@ -71,11 +71,11 @@ class HeaderTest extends PHPUnit_Framework_TestCase { } function testParamsWithArgs() { - $header = new http\Header("Custom", '"foo" is "bar". "bar" is "bis" where "bis" is 3.'); + $header = new http\Header("Custom", '"foo" is "bar". "bar" is "bis" where "bis" is "where".'); $this->assertEquals( array( "foo" => array("value" => "bar", "arguments" => array()), - "bar" => array("value" => "baz", "arguments" => array("baz" => "3")) + "bar" => array("value" => "bis", "arguments" => array("bis" => "where")) ), $header->getParams(".", "where", "is")->params ); -- 2.30.2