Commit:    bb1f9d3826c968ce0c099598ded6f646b3da6429
Author:    Michael Wallner <m...@php.net>         Wed, 14 Aug 2013 14:42:36 
+0200
Parents:   a13c00cd14179971efd60e8acb450a615c2aff22
Branches:  master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=bb1f9d3826c968ce0c099598ded6f646b3da6429

Log:
slim post data

Changed paths:
  M  ext/mbstring/mb_gpc.c
  M  ext/soap/soap.c
  M  ext/standard/php_fopen_wrapper.c
  M  main/SAPI.c
  M  main/SAPI.h
  M  main/main.c
  M  main/php_content_types.c
  M  main/php_globals.h
  M  main/php_streams.h
  M  main/php_variables.c
  M  sapi/cli/php_cli_server.c
  D  tests/basic/024.phpt
  D  tests/basic/026.phpt

diff --git a/ext/mbstring/mb_gpc.c b/ext/mbstring/mb_gpc.c
index 5ecc8f3..30764dc 100644
--- a/ext/mbstring/mb_gpc.c
+++ b/ext/mbstring/mb_gpc.c
@@ -364,6 +364,7 @@ SAPI_POST_HANDLER_FUNC(php_mb_post_handler)
 {
        const mbfl_encoding *detected;
        php_mb_encoding_handler_info_t info;
+       char *post_data_str = NULL;
 
        MBSTRG(http_input_identify_post) = NULL;
 
@@ -376,7 +377,10 @@ SAPI_POST_HANDLER_FUNC(php_mb_post_handler)
        info.num_from_encodings     = MBSTRG(http_input_list_size); 
        info.from_language          = MBSTRG(language);
 
-       detected = _php_mb_encoding_handler_ex(&info, arg, 
SG(request_info).post_data TSRMLS_CC);
+       php_stream_rewind(SG(request_info).request_body);
+       php_stream_copy_to_mem(SG(request_info).request_body, &post_data_str, 
PHP_STREAM_COPY_ALL, 0);
+       detected = _php_mb_encoding_handler_ex(&info, arg, post_data_str 
TSRMLS_CC);
+       STR_FREE(post_data_str);
 
        MBSTRG(http_input_identify) = detected;
        if (detected) {
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index 00e80ef..d10c17e 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -1560,48 +1560,45 @@ PHP_METHOD(SoapServer, handle)
        }
 
        if (ZEND_NUM_ARGS() == 0) {
-               if (SG(request_info).raw_post_data) {
-                       char *post_data = SG(request_info).raw_post_data;
-                       int post_data_length = 
SG(request_info).raw_post_data_length;
+               if (SG(request_info).request_body && 0 == 
php_stream_rewind(SG(request_info).request_body)) {
                        zval **server_vars, **encoding;
+                       php_stream_filter *zf = NULL;
 
                        zend_is_auto_global("_SERVER", sizeof("_SERVER")-1 
TSRMLS_CC);
                        if (zend_hash_find(&EG(symbol_table), "_SERVER", 
sizeof("_SERVER"), (void **) &server_vars) == SUCCESS &&
                            Z_TYPE_PP(server_vars) == IS_ARRAY &&
                            zend_hash_find(Z_ARRVAL_PP(server_vars), 
"HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING"), (void **) 
&encoding)==SUCCESS &&
                            Z_TYPE_PP(encoding) == IS_STRING) {
-                               zval func;
-                               zval retval;
-                               zval param;
-                               zval *params[1];
-
-                               if ((strcmp(Z_STRVAL_PP(encoding),"gzip") == 0 
||
-                                    strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 
0) &&
-                                   zend_hash_exists(EG(function_table), 
"gzinflate", sizeof("gzinflate"))) {
-                                       ZVAL_STRING(&func, "gzinflate", 0);
-                                       params[0] = &param;
-                                       ZVAL_STRINGL(params[0], post_data+10, 
post_data_length-10, 0);
-                                       INIT_PZVAL(params[0]);
-                               } else if 
(strcmp(Z_STRVAL_PP(encoding),"deflate") == 0 &&
-                          zend_hash_exists(EG(function_table), "gzuncompress", 
sizeof("gzuncompress"))) {
-                                       ZVAL_STRING(&func, "gzuncompress", 0);
-                                       params[0] = &param;
-                                       ZVAL_STRINGL(params[0], post_data, 
post_data_length, 0);
-                                       INIT_PZVAL(params[0]);
+
+                               if (strcmp(Z_STRVAL_PP(encoding),"gzip") == 0
+                               ||  strcmp(Z_STRVAL_PP(encoding),"x-gzip") == 0
+                               ||  strcmp(Z_STRVAL_PP(encoding),"deflate") == 0
+                               ) {
+                                       zval filter_params;
+
+                                       INIT_PZVAL(&filter_params);
+                                       array_init_size(&filter_params, 1);
+                                       add_assoc_long_ex(&filter_params, 
ZEND_STRS("window"), 0x2f); /* ANY WBITS */
+
+                                       zf = 
php_stream_filter_create("zlib.inflate", &filter_params, 0);
+                                       zval_dtor(&filter_params);
+
+                                       if (zf) {
+                                               
php_stream_filter_append(&SG(request_info).request_body->readfilters, zf);
+                                       } else {
+                                               php_error_docref(NULL 
TSRMLS_CC, E_WARNING,"Can't uncompress compressed request");
+                                               return;
+                                       }
                                } else {
                                        php_error_docref(NULL TSRMLS_CC, 
E_WARNING,"Request is compressed with unknown compression 
'%s'",Z_STRVAL_PP(encoding));
                                        return;
                                }
-                               if (call_user_function(CG(function_table), 
(zval**)NULL, &func, &retval, 1, params TSRMLS_CC) == SUCCESS &&
-                                   Z_TYPE(retval) == IS_STRING) {
-                                       doc_request = 
soap_xmlParseMemory(Z_STRVAL(retval),Z_STRLEN(retval));
-                                       zval_dtor(&retval);
-                               } else {
-                                       php_error_docref(NULL TSRMLS_CC, 
E_WARNING,"Can't uncompress compressed request");
-                                       return;
-                               }
-                       } else {
-                               doc_request = soap_xmlParseMemory(post_data, 
post_data_length);
+                       }
+
+                       doc_request = soap_xmlParseFile("php://input");
+
+                       if (zf) {
+                               php_stream_filter_remove(zf, 1);
                        }
                } else {
                        zval_ptr_dtor(&retval);
diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c
index 0fb27ba..ca0b92e 100644
--- a/ext/standard/php_fopen_wrapper.c
+++ b/ext/standard/php_fopen_wrapper.c
@@ -71,43 +71,20 @@ static size_t php_stream_input_write(php_stream *stream, 
const char *buf, size_t
 
 static size_t php_stream_input_read(php_stream *stream, char *buf, size_t 
count TSRMLS_DC) /* {{{ */
 {
-       off_t *position = (off_t*)stream->abstract;
-       size_t read_bytes = 0;
-
-       if (!stream->eof) {
-               if (SG(request_info).raw_post_data) { /* data has already been 
read by a post handler */
-                       read_bytes = SG(request_info).raw_post_data_length - 
*position;
-                       if (read_bytes <= count) {
-                               stream->eof = 1;
-                       } else {
-                               read_bytes = count;
-                       }
-                       if (read_bytes) {
-                               memcpy(buf, SG(request_info).raw_post_data + 
*position, read_bytes);
-                       }
-               } else if (sapi_module.read_post) {
-                       read_bytes = sapi_module.read_post(buf, count 
TSRMLS_CC);
-                       if (read_bytes <= 0) {
-                               stream->eof = 1;
-                               read_bytes = 0;
-                       }
-                       /* Increment SG(read_post_bytes) only when something 
was actually read. */
-                       SG(read_post_bytes) += read_bytes;
-               } else {
-                       stream->eof = 1;
-               }
-       }
+       php_stream *inner = stream->abstract;
 
-       *position += read_bytes;
+       if (inner && inner->ops->read) {
+               size_t read = inner->ops->read(inner, buf, count TSRMLS_CC);
+               stream->eof = inner->eof;
+               return read;
+       }
 
-       return read_bytes;
+       return -1;
 }
 /* }}} */
 
 static int php_stream_input_close(php_stream *stream, int close_handle 
TSRMLS_DC) /* {{{ */
 {
-       efree(stream->abstract);
-
        return 0;
 }
 /* }}} */
@@ -118,13 +95,25 @@ static int php_stream_input_flush(php_stream *stream 
TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
+static int php_stream_input_seek(php_stream *stream, off_t offset, int whence, 
off_t *newoffset TSRMLS_DC) /* {{{ */
+{
+       php_stream *inner = stream->abstract;
+
+       if (inner && inner->ops->seek) {
+               return inner->ops->seek(inner, offset, whence, newoffset 
TSRMLS_CC);
+       }
+
+       return -1;
+}
+/* }}} */
+
 php_stream_ops php_stream_input_ops = {
        php_stream_input_write,
        php_stream_input_read,
        php_stream_input_close,
        php_stream_input_flush,
        "Input",
-       NULL, /* seek */
+       php_stream_input_seek,
        NULL, /* cast */
        NULL, /* stat */
        NULL  /* set_option */
@@ -210,7 +199,12 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper 
*wrapper, const char *pa
                        }
                        return NULL;
                }
-               return php_stream_alloc(&php_stream_input_ops, ecalloc(1, 
sizeof(off_t)), 0, "rb");
+               if (SG(request_info).request_body) {
+                       php_stream_rewind(SG(request_info).request_body);
+               } else {
+                       sapi_read_standard_form_data(TSRMLS_C);
+               }
+               return php_stream_alloc(&php_stream_input_ops, 
SG(request_info).request_body, 0, "rb");
        }
 
        if (!strcasecmp(path, "stdin")) {
@@ -259,8 +253,8 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper 
*wrapper, const char *pa
                        fd = dup(STDERR_FILENO);
                }
        } else if (!strncasecmp(path, "fd/", 3)) {
-               char       *start,
-                                  *end;
+               const char *start;
+               char       *end;
                long       fildes_ori;
                int                dtablesize;
 
diff --git a/main/SAPI.c b/main/SAPI.c
index dcb2da6..ccfb1e5 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -180,10 +180,10 @@ SAPI_API void sapi_handle_post(void *arg TSRMLS_DC)
 {
        if (SG(request_info).post_entry && SG(request_info).content_type_dup) {
                
SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, 
arg TSRMLS_CC);
-               if (SG(request_info).post_data) {
-                       efree(SG(request_info).post_data);
-                       SG(request_info).post_data = NULL;
-               }
+               /*if (SG(request_info).request_body) {
+                       php_stream_close(SG(request_info).request_body);
+                       SG(request_info).request_body = NULL;
+               }*/
                efree(SG(request_info).content_type_dup);
                SG(request_info).content_type_dup = NULL;
        }
@@ -253,35 +253,40 @@ static void sapi_read_post_data(TSRMLS_D)
 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data)
 {
        int read_bytes;
-       int allocated_bytes=SAPI_POST_BLOCK_SIZE+1;
 
        if ((SG(post_max_size) > 0) && (SG(request_info).content_length > 
SG(post_max_size))) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "POST 
Content-Length of %ld bytes exceeds the limit of %ld bytes",
                                        SG(request_info).content_length, 
SG(post_max_size));
                return;
        }
-       SG(request_info).post_data = emalloc(allocated_bytes);
+       SG(request_info).request_body = 
php_stream_temp_create(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE);
 
-       for (;;) {
-               read_bytes = 
sapi_module.read_post(SG(request_info).post_data+SG(read_post_bytes), 
SAPI_POST_BLOCK_SIZE TSRMLS_CC);
-               if (read_bytes<=0) {
-                       break;
-               }
-               SG(read_post_bytes) += read_bytes;
-               if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > 
SG(post_max_size))) {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Actual 
POST length does not match Content-Length, and exceeds %ld bytes", 
SG(post_max_size));
-                       break;
-               }
-               if (read_bytes < SAPI_POST_BLOCK_SIZE) {
-                       break;
-               }
-               if (SG(read_post_bytes)+SAPI_POST_BLOCK_SIZE >= 
allocated_bytes) {
-                       allocated_bytes = 
SG(read_post_bytes)+SAPI_POST_BLOCK_SIZE+1;
-                       SG(request_info).post_data = 
erealloc(SG(request_info).post_data, allocated_bytes);
+       if (sapi_module.read_post) {
+               for (;;) {
+                       char buffer[SAPI_POST_BLOCK_SIZE];
+
+                       read_bytes = sapi_module.read_post(buffer, 
SAPI_POST_BLOCK_SIZE TSRMLS_CC);
+                       if (read_bytes<=0) {
+                               /* failure */
+                               break;
+                       }
+                       SG(read_post_bytes) += read_bytes;
+
+                       if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > 
SG(post_max_size))) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Actual POST length does not match Content-Length, and exceeds %ld bytes", 
SG(post_max_size));
+                               break;
+                       }
+
+                       php_stream_write(SG(request_info).request_body, buffer, 
read_bytes);
+
+                       if (read_bytes < SAPI_POST_BLOCK_SIZE) {
+                               /* done */
+                               break;
+                       }
                }
+
+       php_stream_rewind(SG(request_info).request_body);
        }
-       SG(request_info).post_data[SG(read_post_bytes)] = 0;  /* terminating 
NULL */
-       SG(request_info).post_data_length = SG(read_post_bytes);
 }
 
 
@@ -387,8 +392,7 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D)
        SG(sapi_headers).http_status_line = NULL;
        SG(sapi_headers).mimetype = NULL;
        SG(read_post_bytes) = 0;
-       SG(request_info).post_data = NULL;
-       SG(request_info).raw_post_data = NULL;
+       SG(request_info).request_body = NULL;
        SG(request_info).current_user = NULL;
        SG(request_info).current_user_length = 0;
        SG(request_info).no_headers = 0;
@@ -433,8 +437,7 @@ SAPI_API void sapi_activate(TSRMLS_D)
        SG(callback_run) = 0;
        SG(callback_func) = NULL;
        SG(read_post_bytes) = 0;
-       SG(request_info).post_data = NULL;
-       SG(request_info).raw_post_data = NULL;
+       SG(request_info).request_body = NULL;
        SG(request_info).current_user = NULL;
        SG(request_info).current_user_length = 0;
        SG(request_info).no_headers = 0;
@@ -452,14 +455,15 @@ SAPI_API void sapi_activate(TSRMLS_D)
 
        /* Handle request method */
        if (SG(server_context)) {
-               if (PG(enable_post_data_reading) && 
SG(request_info).request_method) {
-                       if (SG(request_info).content_type && 
!strcmp(SG(request_info).request_method, "POST")) {
+               if (SG(request_info).request_method) {
+                       if (PG(enable_post_data_reading)
+                       &&      SG(request_info).content_type
+                       && !strcmp(SG(request_info).request_method, "POST")) {
                                /* HTTP POST may contain form data to be 
processed into variables
                                 * depending on given content type */
                                sapi_read_post_data(TSRMLS_C);
                        } else {
-                               /* Any other method with content payload will 
fill $HTTP_RAW_POST_DATA 
-                                * if it is enabled by 
always_populate_raw_post_data. 
+                               /* Any other method with content payload will 
fill php://input stream.
                                 * It's up to the webserver to decide whether 
to allow a method or not. */
                                SG(request_info).content_type_dup = NULL;
                                if (sapi_module.default_post_reader) {
@@ -494,9 +498,9 @@ static void sapi_send_headers_free(TSRMLS_D)
 SAPI_API void sapi_deactivate(TSRMLS_D)
 {
        zend_llist_destroy(&SG(sapi_headers).headers);
-       if (SG(request_info).post_data) {
-               efree(SG(request_info).post_data);
-       }  else         if (SG(server_context)) {
+       if (SG(request_info).request_body) {
+               SG(request_info).request_body = NULL;
+       }  else if (SG(server_context)) {
                if(sapi_module.read_post) { 
                        /* make sure we've consumed all request input data */
                        char dummy[SAPI_POST_BLOCK_SIZE];
@@ -507,9 +511,6 @@ SAPI_API void sapi_deactivate(TSRMLS_D)
                        }
                }
        }
-       if (SG(request_info).raw_post_data) {
-               efree(SG(request_info).raw_post_data);
-       } 
        if (SG(request_info).auth_user) {
                efree(SG(request_info).auth_user);
        }
diff --git a/main/SAPI.h b/main/SAPI.h
index 6fc60c8..ed6b049 100644
--- a/main/SAPI.h
+++ b/main/SAPI.h
@@ -32,8 +32,7 @@
 #include <sys/stat.h>
 
 #define SAPI_OPTION_NO_CHDIR 1
-
-#define SAPI_POST_BLOCK_SIZE 4000
+#define SAPI_POST_BLOCK_SIZE 0x4000
 
 #ifdef PHP_WIN32
 #      ifdef SAPI_EXPORTS
@@ -80,14 +79,14 @@ END_EXTERN_C()
 typedef struct {
        const char *request_method;
        char *query_string;
-       char *post_data, *raw_post_data;
        char *cookie_data;
        long content_length;
-       int64_t post_data_length, raw_post_data_length;
 
        char *path_translated;
        char *request_uri;
 
+       struct _php_stream *request_body;
+
        const char *content_type;
 
        zend_bool headers_only;
diff --git a/main/main.c b/main/main.c
index 2f56afa..1cc842b 100644
--- a/main/main.c
+++ b/main/main.c
@@ -562,7 +562,6 @@ PHP_INI_BEGIN()
        STD_PHP_INI_BOOLEAN("allow_url_fopen",          "1",            
PHP_INI_SYSTEM,         OnUpdateBool,           allow_url_fopen,                
php_core_globals,               core_globals)
        STD_PHP_INI_BOOLEAN("allow_url_include",        "0",            
PHP_INI_SYSTEM,         OnUpdateBool,           allow_url_include,              
php_core_globals,               core_globals)
        STD_PHP_INI_BOOLEAN("enable_post_data_reading", "1",    
PHP_INI_SYSTEM|PHP_INI_PERDIR,  OnUpdateBool,   enable_post_data_reading,       
php_core_globals,       core_globals)
-       STD_PHP_INI_BOOLEAN("always_populate_raw_post_data",    "0",    
PHP_INI_SYSTEM|PHP_INI_PERDIR,  OnUpdateBool,   always_populate_raw_post_data,  
php_core_globals,       core_globals)
 
        STD_PHP_INI_ENTRY("realpath_cache_size",        "16K",          
PHP_INI_SYSTEM,         OnUpdateLong,   realpath_cache_size_limit,      
virtual_cwd_globals,    cwd_globals)
        STD_PHP_INI_ENTRY("realpath_cache_ttl",         "120",          
PHP_INI_SYSTEM,         OnUpdateLong,   realpath_cache_ttl,                     
virtual_cwd_globals,    cwd_globals)
diff --git a/main/php_content_types.c b/main/php_content_types.c
index c443397..3346efc 100644
--- a/main/php_content_types.c
+++ b/main/php_content_types.c
@@ -37,34 +37,11 @@ static sapi_post_entry php_post_entries[] = {
  */
 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader)
 {
-       char *data;
-       int length;
-
-       /* $HTTP_RAW_POST_DATA registration */
        if (!strcmp(SG(request_info).request_method, "POST")) {
                if (NULL == SG(request_info).post_entry) {
                        /* no post handler registered, so we just swallow the 
data */
                        sapi_read_standard_form_data(TSRMLS_C);
                }
-
-               /* For unknown content types we create HTTP_RAW_POST_DATA even 
if always_populate_raw_post_data off,
-                * this is in-effecient, but we need to keep doing it for BC 
reasons (for now) */
-               if ((PG(always_populate_raw_post_data) || NULL == 
SG(request_info).post_entry) && SG(request_info).post_data) {
-                       length = SG(request_info).post_data_length;
-                       data = estrndup(SG(request_info).post_data, length);
-                       SET_VAR_STRINGL("HTTP_RAW_POST_DATA", data, length);
-               }
-       }
-
-       /* for php://input stream:
-        some post handlers modify the content of request_info.post_data
-        so for now we need a copy for the php://input stream
-        in the long run post handlers should be changed to not touch
-        request_info.post_data for memory preservation reasons
-       */
-       if (SG(request_info).post_data) {
-               SG(request_info).raw_post_data = 
estrndup(SG(request_info).post_data, SG(request_info).post_data_length);
-               SG(request_info).raw_post_data_length = 
SG(request_info).post_data_length;
        }
 }
 /* }}} */
diff --git a/main/php_globals.h b/main/php_globals.h
index 256765d..fa2fe3b 100644
--- a/main/php_globals.h
+++ b/main/php_globals.h
@@ -131,7 +131,6 @@ struct _php_core_globals {
        zend_bool during_request_startup;
        zend_bool allow_url_fopen;
        zend_bool enable_post_data_reading;
-       zend_bool always_populate_raw_post_data;
        zend_bool report_zend_debug;
 
        int last_error_type;
diff --git a/main/php_streams.h b/main/php_streams.h
index c56014c..c9732b4 100644
--- a/main/php_streams.h
+++ b/main/php_streams.h
@@ -242,7 +242,7 @@ PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, 
void *abstract,
 END_EXTERN_C()
 #define php_stream_alloc(ops, thisptr, persistent_id, mode)    
_php_stream_alloc((ops), (thisptr), (persistent_id), (mode) STREAMS_CC 
TSRMLS_CC)
 
-#define php_stream_get_resource_id(stream)             (stream)->rsrc_id
+#define php_stream_get_resource_id(stream)             ((php_stream 
*)(stream))->rsrc_id
 #if ZEND_DEBUG
 /* use this to tell the stream that it is OK if we don't explicitly close it */
 # define php_stream_auto_cleanup(stream)       { (stream)->__exposed++; }
diff --git a/main/php_variables.c b/main/php_variables.c
index 7018eae..af3a6aa 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -23,6 +23,7 @@
 #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"
@@ -228,44 +229,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);
+               }
        }
 }
 
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c
index cbe9c7b..dbd861a 100644
--- a/sapi/cli/php_cli_server.c
+++ b/sapi/cli/php_cli_server.c
@@ -1726,8 +1726,7 @@ static void 
php_cli_server_client_populate_request_info(const php_cli_server_cli
        request_info->request_uri = client->request.request_uri;
        request_info->path_translated = client->request.path_translated;
        request_info->query_string = client->request.query_string;
-       request_info->post_data = client->request.content;
-       request_info->content_length = request_info->post_data_length = 
client->request.content_len;
+       request_info->content_length = client->request.content_len;
        request_info->auth_user = request_info->auth_password = 
request_info->auth_digest = NULL;
        if (SUCCESS == zend_hash_find(&client->request.headers, "Content-Type", 
sizeof("Content-Type"), (void**)&val)) {
                request_info->content_type = *val;
diff --git a/tests/basic/024.phpt b/tests/basic/024.phpt
deleted file mode 100644
index bf8a206..0000000
--- a/tests/basic/024.phpt
+++ /dev/null
@@ -1,28 +0,0 @@
---TEST--
-Test HTTP_RAW_POST_DATA creation
---INI--
-always_populate_raw_post_data=1
-max_input_vars=1000
---POST--
-a=ABC&y=XYZ&c[]=1&c[]=2&c[a]=3
---FILE--
-<?php
-var_dump($_POST, $HTTP_RAW_POST_DATA);
-?>
---EXPECT--
-array(3) {
-  ["a"]=>
-  string(3) "ABC"
-  ["y"]=>
-  string(3) "XYZ"
-  ["c"]=>
-  array(3) {
-    [0]=>
-    string(1) "1"
-    [1]=>
-    string(1) "2"
-    ["a"]=>
-    string(1) "3"
-  }
-}
-string(30) "a=ABC&y=XYZ&c[]=1&c[]=2&c[a]=3"
diff --git a/tests/basic/026.phpt b/tests/basic/026.phpt
deleted file mode 100644
index b98a31f..0000000
--- a/tests/basic/026.phpt
+++ /dev/null
@@ -1,15 +0,0 @@
---TEST--
-Registration of HTTP_RAW_POST_DATA due to unknown content-type
---INI--
-always_populate_raw_post_data=0
---POST_RAW--
-Content-Type: unknown/type
-a=1&b=ZYX
---FILE--
-<?php
-var_dump($_POST, $HTTP_RAW_POST_DATA);
-?>
---EXPECT--
-array(0) {
-}
-string(9) "a=1&b=ZYX"
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to