diff options
author | Stanley Sufficool <ssufficool@php.net> | 2013-10-05 17:57:23 -0700 |
---|---|---|
committer | Stanley Sufficool <ssufficool@php.net> | 2013-10-05 17:57:23 -0700 |
commit | 3e023c3ddf9e80046803a989f4951ee16d3b8f9b (patch) | |
tree | 602f3b798d09f49f069fd9a046d502931f56c158 /main/php_variables.c | |
parent | b144c263191f857391d3cc009951c95d25a2cdb3 (diff) | |
parent | 3261eb348f5aea14f74010d883cfc68978fd8ed9 (diff) | |
download | php-git-3e023c3ddf9e80046803a989f4951ee16d3b8f9b.tar.gz |
Merge branch 'master' of https://git.php.net/push/php-src
* 'master' of https://git.php.net/push/php-src: (705 commits)
Allow the ldap extension to be compiled with Oracle's LDAP implementation, if desired. Note the implementations differ so you will see different ldap behavior.
Fix bug #65667: ftp_nb_continue produces segfault
fix bug #64146 (serialize incorrectly saving objects when they are cloned)
such a weird hack probably helps in finding regressions in the future
Fix bug #65821: By-ref foreach on property access of string offset segfaults
Fixed bug #64230 (XMLReader does not suppress errors)
add NEWS and UPGRADING about gost-crypto
fix bug #55285 XMLReader::getAttribute/No/Ns methods inconsistency
typo: really fix bug #51936 Crash with clone xmlreader
fix bug #59613 (Crash with clone XMLReader)
Fix Bug #60633 build warning in bcmath
fix bug #65808 the socket_connect() won't work with IPv6 address
5.4.22-dev now
Revert "Make 'make distclean' remove the downloaded pear PHAR"
fix bug #62396 'make test' crashes starting with 5.3.14 (missing gzencode())
Fixed bug #61548
Reverted patch (it was used for internal testing and was committed by accident)
OCI8 2.0: Added a new oci_set_db_operation() user space function for the "DB Operation" tracing feature of Oracle DB 12c.
Make 'make distclean' remove the downloaded pear PHAR
fix test
...
Diffstat (limited to 'main/php_variables.c')
-rw-r--r-- | main/php_variables.c | 133 |
1 files changed, 104 insertions, 29 deletions
diff --git a/main/php_variables.c b/main/php_variables.c index fd52f311d1..ab9aee3ae3 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -23,11 +23,15 @@ #include "php.h" #include "ext/standard/php_standard.h" #include "ext/standard/credits.h" +#include "ext/standard/php_smart_str.h" #include "php_variables.h" #include "php_globals.h" #include "php_content_types.h" #include "SAPI.h" #include "zend_globals.h" +#ifdef PHP_WIN32 +# include "win32/php_inttypes.h" +#endif /* for systems that need to override reading of environment variables */ void _php_import_environment_variables(zval *array_ptr TSRMLS_DC); @@ -55,7 +59,7 @@ PHPAPI void php_register_variable_safe(char *var, char *strval, int str_len, zva PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array TSRMLS_DC) { char *p = NULL; - char *ip; /* index pointer */ + char *ip = NULL; /* index pointer */ char *index; char *var, *var_orig; int var_len, index_len; @@ -228,44 +232,115 @@ plain_var: free_alloca(var_orig, use_heap); } +typedef struct post_var_data { + smart_str str; + char *ptr; + char *end; + uint64_t cnt; +} post_var_data_t; + +static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof TSRMLS_DC) +{ + char *ksep, *vsep; + size_t klen, vlen; + /* FIXME: string-size_t */ + unsigned int new_vlen; + + if (var->ptr >= var->end) { + return 0; + } + + vsep = memchr(var->ptr, '&', var->end - var->ptr); + if (!vsep) { + if (!eof) { + return 0; + } else { + vsep = var->end; + } + } + + ksep = memchr(var->ptr, '=', vsep - var->ptr); + if (ksep) { + *ksep = '\0'; + /* "foo=bar&" or "foo=&" */ + klen = ksep - var->ptr; + vlen = vsep - ++ksep; + } else { + ksep = ""; + /* "foo&" */ + klen = vsep - var->ptr; + vlen = 0; + } + + + php_url_decode(var->ptr, klen); + if (vlen) { + vlen = php_url_decode(ksep, vlen); + } + + if (sapi_module.input_filter(PARSE_POST, var->ptr, &ksep, vlen, &new_vlen TSRMLS_CC)) { + php_register_variable_safe(var->ptr, ksep, new_vlen, arr TSRMLS_CC); + } + + var->ptr = vsep + (vsep != var->end); + return 1; +} + +static inline int add_post_vars(zval *arr, post_var_data_t *vars, zend_bool eof TSRMLS_DC) +{ + uint64_t max_vars = PG(max_input_vars); + + vars->ptr = vars->str.c; + vars->end = vars->str.c + vars->str.len; + while (add_post_var(arr, vars, eof TSRMLS_CC)) { + if (++vars->cnt > max_vars) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Input variables exceeded %" PRIu64 ". " + "To increase the limit change max_input_vars in php.ini.", + max_vars); + return FAILURE; + } + } + + if (!eof) { + memmove(vars->str.c, vars->ptr, vars->str.len = vars->end - vars->ptr); + } + return SUCCESS; +} + SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler) { - char *var, *val, *e, *s, *p; - zval *array_ptr = (zval *) arg; - long count = 0; + zval *arr = (zval *) arg; + php_stream *s = SG(request_info).request_body; + post_var_data_t post_data; - if (SG(request_info).post_data == NULL) { - return; - } + if (s && SUCCESS == php_stream_rewind(s)) { + memset(&post_data, 0, sizeof(post_data)); - s = SG(request_info).post_data; - e = s + SG(request_info).post_data_length; + while (!php_stream_eof(s)) { + char buf[BUFSIZ] = {0}; + size_t len = php_stream_read(s, buf, BUFSIZ); - while (s < e && (p = memchr(s, '&', (e - s)))) { -last_value: - if ((val = memchr(s, '=', (p - s)))) { /* have a value */ - unsigned int val_len, new_val_len; + if (len && len != (size_t) -1) { + smart_str_appendl(&post_data.str, buf, len); - if (++count > PG(max_input_vars)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); - return; + if (SUCCESS != add_post_vars(arr, &post_data, 0 TSRMLS_CC)) { + if (post_data.str.c) { + efree(post_data.str.c); + } + return; + } } - var = s; - php_url_decode(var, (val - s)); - val++; - val_len = php_url_decode(val, (p - val)); - val = estrndup(val, val_len); - if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { - php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); + if (len != BUFSIZ){ + break; } - efree(val); } - s = p + 1; - } - if (s < e) { - p = e; - goto last_value; + + add_post_vars(arr, &post_data, 1 TSRMLS_CC); + if (post_data.str.c) { + efree(post_data.str.c); + } } } |