less intrusive fix
[m6w6/ext-http] / php_http_params.c
index f7c7b7bb09966895f54bda98e87faa05ced60095..f9df1c4883e5a3028afa1b4aff056f69121437da 100644 (file)
     +--------------------------------------------------------------------+
 */
 
-#include "php_http.h"
-
-#include <ext/standard/php_string.h>
-#include <Zend/zend_interfaces.h>
+#include "php_http_api.h"
 
 static php_http_params_token_t def_param_sep = {",", 1}, *def_param_sep_ptr[] = {&def_param_sep, NULL};
 static php_http_params_token_t def_arg_sep = {";", 1}, *def_arg_sep_ptr[] = {&def_arg_sep, NULL};
@@ -47,42 +44,62 @@ typedef struct php_http_params_state {
        } current;
 } php_http_params_state_t;
 
+static inline void sanitize_string(char *str, size_t len, zval *zv TSRMLS_DC)
+{
+       /* trim whitespace */
+       php_trim(str, len, NULL, 0, zv, 3 TSRMLS_CC);
+
+       /* dequote */
+       if (Z_STRVAL_P(zv)[0] == '"' && Z_STRVAL_P(zv)[Z_STRLEN_P(zv) - 1] == '"') {
+               size_t deq_len = Z_STRLEN_P(zv) - 2;
+               char *deq = estrndup(Z_STRVAL_P(zv) + 1, deq_len);
+
+               zval_dtor(zv);
+               ZVAL_STRINGL(zv, deq, deq_len, 0);
+       }
+
+       /* strip slashes */
+       php_stripslashes(Z_STRVAL_P(zv), &Z_STRLEN_P(zv) TSRMLS_CC);
+}
+
 static void push_param(HashTable *params, php_http_params_state_t *state, const php_http_params_opts_t *opts TSRMLS_DC)
 {
        if (state->val.str) {
                if (0 < (state->val.len = state->input.str - state->val.str)) {
-                       php_trim(state->val.str, state->val.len, NULL, 0, *(state->current.val), 3 TSRMLS_CC);
+                       sanitize_string(state->val.str, state->val.len, *(state->current.val) TSRMLS_CC);
                }
        } else if (state->arg.str) {
                if (0 < (state->arg.len = state->input.str - state->arg.str)) {
                        zval *val, key;
 
                        INIT_PZVAL(&key);
-                       php_trim(state->arg.str, state->arg.len, NULL, 0, &key, 3 TSRMLS_CC);
-                       MAKE_STD_ZVAL(val);
-                       ZVAL_TRUE(val);
-                       zend_symtable_update(Z_ARRVAL_PP(state->current.args), Z_STRVAL(key), Z_STRLEN(key) + 1, (void *) &val, sizeof(zval *), (void *) &state->current.val);
-
+                       sanitize_string(state->arg.str, state->arg.len, &key TSRMLS_CC);
+                       if (Z_STRLEN(key)) {
+                               MAKE_STD_ZVAL(val);
+                               ZVAL_TRUE(val);
+                               zend_symtable_update(Z_ARRVAL_PP(state->current.args), Z_STRVAL(key), Z_STRLEN(key) + 1, (void *) &val, sizeof(zval *), (void *) &state->current.val);
+                       }
                        zval_dtor(&key);
                }
        } else if (state->param.str) {
                if (0 < (state->param.len = state->input.str - state->param.str)) {
                        zval *prm, *arg, *val, key;
 
-                       MAKE_STD_ZVAL(prm);
-                       array_init(prm);
-                       MAKE_STD_ZVAL(val);
-                       ZVAL_TRUE(val);
-                       zend_hash_update(Z_ARRVAL_P(prm), "value", sizeof("value"), (void *) &val, sizeof(zval *), (void *) &state->current.val);
-
-                       MAKE_STD_ZVAL(arg);
-                       array_init(arg);
-                       zend_hash_update(Z_ARRVAL_P(prm), "arguments", sizeof("arguments"), (void *) &arg, sizeof(zval *), (void *) &state->current.args);
-
                        INIT_PZVAL(&key);
-                       php_trim(state->param.str, state->param.len, NULL, 0, &key, 3 TSRMLS_CC);
-                       zend_symtable_update(params, Z_STRVAL(key), Z_STRLEN(key) + 1, (void *) &prm, sizeof(zval *), (void *) &state->current.param);
-
+                       sanitize_string(state->param.str, state->param.len, &key TSRMLS_CC);
+                       if (Z_STRLEN(key)) {
+                               MAKE_STD_ZVAL(prm);
+                               array_init(prm);
+                               MAKE_STD_ZVAL(val);
+                               ZVAL_TRUE(val);
+                               zend_hash_update(Z_ARRVAL_P(prm), "value", sizeof("value"), (void *) &val, sizeof(zval *), (void *) &state->current.val);
+
+                               MAKE_STD_ZVAL(arg);
+                               array_init(arg);
+                               zend_hash_update(Z_ARRVAL_P(prm), "arguments", sizeof("arguments"), (void *) &arg, sizeof(zval *), (void *) &state->current.args);
+
+                               zend_symtable_update(params, Z_STRVAL(key), Z_STRLEN(key) + 1, (void *) &prm, sizeof(zval *), (void *) &state->current.param);
+                       }
                        zval_dtor(&key);
                }
        }
@@ -179,7 +196,9 @@ PHP_HTTP_API HashTable *php_http_params_parse(HashTable *params, const php_http_
 
 PHP_HTTP_BEGIN_ARGS(__construct, 0)
        PHP_HTTP_ARG_VAL(params, 0)
-       PHP_HTTP_ARG_VAL(flags, 0)
+       PHP_HTTP_ARG_VAL(param_sep, 0)
+       PHP_HTTP_ARG_VAL(arg_sep, 0)
+       PHP_HTTP_ARG_VAL(val_sep, 0)
 PHP_HTTP_END_ARGS;
 
 PHP_HTTP_EMPTY_ARGS(toArray);
@@ -287,11 +306,14 @@ PHP_METHOD(HttpParams, __construct)
                if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!/z/z/z/", &zparams, &param_sep, &arg_sep, &val_sep)) {
                        switch (ZEND_NUM_ARGS()) {
                                case 4:
-                                       zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), param_sep TSRMLS_CC);
+                                       zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), val_sep TSRMLS_CC);
+                                       /* no break */
                                case 3:
                                        zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("arg_sep"), arg_sep TSRMLS_CC);
+                                       /* no break */
                                case 2:
-                                       zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("val_sep"), val_sep TSRMLS_CC);
+                                       zend_update_property(php_http_params_class_entry, getThis(), ZEND_STRL("param_sep"), param_sep TSRMLS_CC);
+                                       /* no break */
                        }
 
                        if (zparams) {
@@ -403,9 +425,17 @@ PHP_METHOD(HttpParams, toString)
                                                /* add value */
                                                if (Z_TYPE_PP(zarg) != IS_BOOL) {
                                                        zval *tmp = php_http_ztyp(IS_STRING, *zarg);
+                                                       int escaped_len;
 
+                                                       Z_STRVAL_P(tmp) = php_addslashes(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp), &escaped_len, 1 TSRMLS_CC);
                                                        php_http_buffer_append(&buf, Z_STRVAL_P(zvsep), Z_STRLEN_P(zvsep));
-                                                       php_http_buffer_append(&buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
+                                                       if (escaped_len != Z_STRLEN_P(tmp)) {
+                                                               php_http_buffer_appends(&buf, "\"");
+                                                               php_http_buffer_append(&buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp) = escaped_len);
+                                                               php_http_buffer_appends(&buf, "\"");
+                                                       } else {
+                                                               php_http_buffer_append(&buf, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
+                                                       }
                                                        zval_ptr_dtor(&tmp);
                                                } else if (!Z_BVAL_PP(zarg)) {
                                                        php_http_buffer_append(&buf, Z_STRVAL_P(zvsep), Z_STRLEN_P(zvsep));
@@ -422,6 +452,7 @@ PHP_METHOD(HttpParams, toString)
        zval_ptr_dtor(&zasep);
        zval_ptr_dtor(&zvsep);
 
+       php_http_buffer_fix(&buf);
        php_http_buffer_shrink(&buf);
        RETVAL_PHP_HTTP_BUFFER_VAL(&buf);
 }