mirror of
https://github.com/php/php-src.git
synced 2025-08-20 09:24:05 +02:00
MFB: Fixed bug #38236 (Binary data gets corrupted on multipart/formdata
POST).
This commit is contained in:
parent
0e29c9a870
commit
d2579f9dd1
2 changed files with 40 additions and 30 deletions
|
@ -341,8 +341,7 @@ plain_var:
|
||||||
|
|
||||||
SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
|
SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
|
||||||
{
|
{
|
||||||
char *var, *val;
|
char *var, *val, *e, *s, *p;
|
||||||
char *strtok_buf = NULL;
|
|
||||||
zval *array_ptr = (zval *) arg;
|
zval *array_ptr = (zval *) arg;
|
||||||
UConverter *input_conv = UG(http_input_encoding_conv);
|
UConverter *input_conv = UG(http_input_encoding_conv);
|
||||||
|
|
||||||
|
@ -354,11 +353,12 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
|
||||||
input_conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
|
input_conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
|
||||||
}
|
}
|
||||||
|
|
||||||
var = php_strtok_r(SG(request_info).post_data, "&", &strtok_buf);
|
s = SG(request_info).post_data;
|
||||||
|
e = s + SG(request_info).post_data_length;
|
||||||
|
|
||||||
while (var) {
|
while (s < e && (p = memchr(s, '&', (e - s)))) {
|
||||||
val = strchr(var, '=');
|
last_value:
|
||||||
if (val) { /* have a value */
|
if ((val = memchr(s, '=', (p - s)))) { /* have a value */
|
||||||
if (UG(unicode)) {
|
if (UG(unicode)) {
|
||||||
UChar *u_var, *u_val;
|
UChar *u_var, *u_val;
|
||||||
int u_var_len, u_val_len;
|
int u_var_len, u_val_len;
|
||||||
|
@ -366,10 +366,12 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
|
||||||
int val_len;
|
int val_len;
|
||||||
UErrorCode status1 = U_ZERO_ERROR, status2 = U_ZERO_ERROR;
|
UErrorCode status1 = U_ZERO_ERROR, status2 = U_ZERO_ERROR;
|
||||||
|
|
||||||
*val++ = '\0';
|
var = s;
|
||||||
var_len = strlen(var);
|
var_len = val - s;
|
||||||
|
|
||||||
php_url_decode(var, var_len);
|
php_url_decode(var, var_len);
|
||||||
val_len = php_url_decode(val, strlen(val));
|
val++;
|
||||||
|
val_len = php_url_decode(val, (p - val));
|
||||||
zend_convert_to_unicode(input_conv, &u_var, &u_var_len, var, var_len, &status1);
|
zend_convert_to_unicode(input_conv, &u_var, &u_var_len, var, var_len, &status1);
|
||||||
zend_convert_to_unicode(input_conv, &u_val, &u_val_len, val, val_len, &status2);
|
zend_convert_to_unicode(input_conv, &u_val, &u_val_len, val, val_len, &status2);
|
||||||
if (U_SUCCESS(status1) && U_SUCCESS(status2)) {
|
if (U_SUCCESS(status1) && U_SUCCESS(status2)) {
|
||||||
|
@ -383,9 +385,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
|
||||||
} else {
|
} else {
|
||||||
unsigned int val_len, new_val_len;
|
unsigned int val_len, new_val_len;
|
||||||
|
|
||||||
*val++ = '\0';
|
var = s;
|
||||||
php_url_decode(var, strlen(var));
|
|
||||||
val_len = php_url_decode(val, strlen(val));
|
php_url_decode(var, (val - s));
|
||||||
|
val++;
|
||||||
|
val_len = php_url_decode(val, (p - val));
|
||||||
val = estrndup(val, val_len);
|
val = estrndup(val, val_len);
|
||||||
if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
|
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);
|
php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
|
||||||
|
@ -393,7 +397,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
|
||||||
efree(val);
|
efree(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var = php_strtok_r(NULL, "&", &strtok_buf);
|
s = p + 1;
|
||||||
|
}
|
||||||
|
if (s < e) {
|
||||||
|
p = e;
|
||||||
|
goto last_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
|
#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
|
||||||
#include "ext/mbstring/mbstring.h"
|
#include "ext/mbstring/mbstring.h"
|
||||||
|
|
||||||
static void safe_php_register_variable(char *var, char *strval, zval *track_vars_array, zend_bool override_protection TSRMLS_DC);
|
static void safe_php_register_variable(char *var, char *strval, int val_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC);
|
||||||
|
|
||||||
void php_mb_flush_gpc_variables(int num_vars, char **val_list, int *len_list, zval *array_ptr TSRMLS_DC)
|
void php_mb_flush_gpc_variables(int num_vars, char **val_list, int *len_list, zval *array_ptr TSRMLS_DC)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,7 @@ void php_mb_flush_gpc_variables(int num_vars, char **val_list, int *len_list, zv
|
||||||
php_mb_gpc_encoding_converter(val_list, len_list, num_vars, NULL, NULL TSRMLS_CC);
|
php_mb_gpc_encoding_converter(val_list, len_list, num_vars, NULL, NULL TSRMLS_CC);
|
||||||
}
|
}
|
||||||
for (i=0; i<num_vars; i+=2){
|
for (i=0; i<num_vars; i+=2){
|
||||||
safe_php_register_variable(val_list[i], val_list[i+1], array_ptr, 0 TSRMLS_CC);
|
safe_php_register_variable(val_list[i], val_list[i+1], len_list[i+1], array_ptr, 0 TSRMLS_CC);
|
||||||
efree(val_list[i]);
|
efree(val_list[i]);
|
||||||
efree(val_list[i+1]);
|
efree(val_list[i+1]);
|
||||||
}
|
}
|
||||||
|
@ -282,10 +282,10 @@ static zend_bool is_u_protected_variable(UChar *varname TSRMLS_DC)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void safe_php_register_variable(char *var, char *strval, zval *track_vars_array, zend_bool override_protection TSRMLS_DC)
|
static void safe_php_register_variable(char *var, char *strval, int val_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC)
|
||||||
{
|
{
|
||||||
if (override_protection || !is_protected_variable(var TSRMLS_CC)) {
|
if (override_protection || !is_protected_variable(var TSRMLS_CC)) {
|
||||||
php_register_variable(var, strval, track_vars_array TSRMLS_CC);
|
php_register_variable_safe(var, strval, val_len, track_vars_array TSRMLS_CC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ static void safe_u_php_register_variable_ex(UChar *var, zval *val, zval *track_v
|
||||||
|
|
||||||
static void register_http_post_files_variable(char *strvar, char *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC)
|
static void register_http_post_files_variable(char *strvar, char *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC)
|
||||||
{
|
{
|
||||||
safe_php_register_variable(strvar, val, http_post_files, override_protection TSRMLS_CC);
|
safe_php_register_variable(strvar, val, strlen(val), http_post_files, override_protection TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -980,7 +980,7 @@ static int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes, i
|
||||||
XXX: this is horrible memory-usage-wise, but we only expect
|
XXX: this is horrible memory-usage-wise, but we only expect
|
||||||
to do this on small pieces of form data.
|
to do this on small pieces of form data.
|
||||||
*/
|
*/
|
||||||
static char *multipart_buffer_read_body(multipart_buffer *self TSRMLS_DC)
|
static char *multipart_buffer_read_body(multipart_buffer *self, unsigned int *len TSRMLS_DC)
|
||||||
{
|
{
|
||||||
char buf[FILLUNIT], *out=NULL;
|
char buf[FILLUNIT], *out=NULL;
|
||||||
int total_bytes=0, read_bytes=0;
|
int total_bytes=0, read_bytes=0;
|
||||||
|
@ -992,6 +992,7 @@ static char *multipart_buffer_read_body(multipart_buffer *self TSRMLS_DC)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out) out[total_bytes] = '\0';
|
if (out) out[total_bytes] = '\0';
|
||||||
|
*len = total_bytes;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -1142,14 +1143,15 @@ static SAPI_POST_HANDLER_FUNC(rfc1867_post_handler_unicode)
|
||||||
if (!filename && param) {
|
if (!filename && param) {
|
||||||
UChar *u_val;
|
UChar *u_val;
|
||||||
int32_t u_val_len;
|
int32_t u_val_len;
|
||||||
|
unsigned int value_len;
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
|
||||||
char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
|
char *value = multipart_buffer_read_body(mbuff, &value_len TSRMLS_CC);
|
||||||
/* unsigned int new_val_len; Dummy variable */
|
/* unsigned int new_val_len; Dummy variable */
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
/* UTODO use 'charset' parameter for conversion */
|
/* UTODO use 'charset' parameter for conversion */
|
||||||
zend_convert_to_unicode(input_conv, &u_val, &u_val_len, value, strlen(value), &status);
|
zend_convert_to_unicode(input_conv, &u_val, &u_val_len, value, value_len, &status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
/* UTODO set a user-accessible flag to indicate that conversion failed? */
|
/* UTODO set a user-accessible flag to indicate that conversion failed? */
|
||||||
goto var_done;
|
goto var_done;
|
||||||
|
@ -1597,24 +1599,24 @@ static SAPI_POST_HANDLER_FUNC(rfc1867_post_handler_legacy)
|
||||||
|
|
||||||
/* Normal form variable, safe to read all data into memory */
|
/* Normal form variable, safe to read all data into memory */
|
||||||
if (!filename && param) {
|
if (!filename && param) {
|
||||||
|
unsigned int value_len;
|
||||||
char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
|
char *value = multipart_buffer_read_body(mbuff, &value_len TSRMLS_CC);
|
||||||
unsigned int new_val_len; /* Dummy variable */
|
unsigned int new_val_len; /* Dummy variable */
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
value = estrdup("");
|
value = estrdup("");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
|
if (sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC)) {
|
||||||
#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
|
#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
|
||||||
if (php_mb_encoding_translation(TSRMLS_C)) {
|
if (php_mb_encoding_translation(TSRMLS_C)) {
|
||||||
php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
|
php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
|
||||||
&num_vars, &num_vars_max TSRMLS_CC);
|
&num_vars, &num_vars_max TSRMLS_CC);
|
||||||
} else {
|
} else {
|
||||||
safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
|
safe_php_register_variable(param, value, value_len, array_ptr, 0 TSRMLS_CC);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
|
safe_php_register_variable(param, value, value_len, array_ptr, 0 TSRMLS_CC);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!strcasecmp(param, "MAX_FILE_SIZE")) {
|
if (!strcasecmp(param, "MAX_FILE_SIZE")) {
|
||||||
|
@ -1814,9 +1816,9 @@ filedone:
|
||||||
|
|
||||||
if (!is_anonymous) {
|
if (!is_anonymous) {
|
||||||
if (s && s > filename) {
|
if (s && s > filename) {
|
||||||
safe_php_register_variable(lbuf, s+1, NULL, 0 TSRMLS_CC);
|
safe_php_register_variable(lbuf, s+1, strlen(s+1), NULL, 0 TSRMLS_CC);
|
||||||
} else {
|
} else {
|
||||||
safe_php_register_variable(lbuf, filename, NULL, 0 TSRMLS_CC);
|
safe_php_register_variable(lbuf, filename, strlen(filename), NULL, 0 TSRMLS_CC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1852,7 +1854,7 @@ filedone:
|
||||||
sprintf(lbuf, "%s_type", param);
|
sprintf(lbuf, "%s_type", param);
|
||||||
}
|
}
|
||||||
if (!is_anonymous) {
|
if (!is_anonymous) {
|
||||||
safe_php_register_variable(lbuf, cd, NULL, 0 TSRMLS_CC);
|
safe_php_register_variable(lbuf, cd, strlen(cd), NULL, 0 TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add $foo[type] */
|
/* Add $foo[type] */
|
||||||
|
@ -1874,7 +1876,7 @@ filedone:
|
||||||
|
|
||||||
/* if param is of form xxx[.*] this will cut it to xxx */
|
/* if param is of form xxx[.*] this will cut it to xxx */
|
||||||
if (!is_anonymous) {
|
if (!is_anonymous) {
|
||||||
safe_php_register_variable(param, temp_filename, NULL, 1 TSRMLS_CC);
|
safe_php_register_variable(param, temp_filename, strlen(temp_filename), NULL, 1 TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add $foo[tmp_name] */
|
/* Add $foo[tmp_name] */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue