1999-06-13 01:50:39 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-09-20 00:33:14 +08:00
| PHP Version 7 |
1999-06-13 01:50:39 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-01-03 11:08:10 +08:00
| Copyright ( c ) 1997 - 2014 The PHP Group |
1999-06-13 01:50:39 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
1999-07-16 21:13:16 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
1999-07-16 21:13:16 +08:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
1999-06-13 01:50:39 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-06-04 13:46:28 +08:00
| Authors : Rasmus Lerdorf < rasmus @ php . net > |
2009-12-30 02:59:58 +08:00
| Jani Taskinen < jani @ php . net > |
1999-06-13 01:50:39 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2003-02-19 16:40:19 +08:00
1999-06-13 01:50:39 +08:00
/* $Id$ */
2001-10-30 03:12:43 +08:00
/*
* This product includes software developed by the Apache Group
* for use in the Apache HTTP server project ( http : //www.apache.org/).
*
2009-12-30 02:59:58 +08:00
*/
2001-10-30 02:58:15 +08:00
1999-06-13 01:50:39 +08:00
# include <stdio.h>
# include "php.h"
2000-09-12 02:56:47 +08:00
# include "php_open_temporary_file.h"
1999-06-13 01:50:39 +08:00
# include "zend_globals.h"
# include "php_globals.h"
2000-01-29 01:24:53 +08:00
# include "php_variables.h"
1999-05-26 06:28:24 +08:00
# include "rfc1867.h"
2009-12-29 23:57:54 +08:00
# include "ext/standard/php_string.h"
1999-05-26 06:28:24 +08:00
2013-07-23 13:39:36 +08:00
# if defined(PHP_WIN32) && !defined(HAVE_ATOLL)
2013-07-23 03:26:38 +08:00
# define atoll(s) _atoi64(s)
2014-07-21 15:52:52 +08:00
# define HAVE_ATOLL 1
2013-07-23 03:26:38 +08:00
# endif
2004-03-26 05:27:23 +08:00
# define DEBUG_FILE_UPLOAD ZEND_DEBUG
2003-10-22 22:14:05 +08:00
2010-12-08 19:27:34 +08:00
static int dummy_encoding_translation ( TSRMLS_D )
{
return 0 ;
}
2006-07-23 00:38:29 +08:00
2011-03-06 15:00:30 +08:00
static char * php_ap_getword ( const zend_encoding * encoding , char * * line , char stop TSRMLS_DC ) ;
static char * php_ap_getword_conf ( const zend_encoding * encoding , char * str TSRMLS_DC ) ;
2010-12-08 19:27:34 +08:00
static php_rfc1867_encoding_translation_t php_rfc1867_encoding_translation = dummy_encoding_translation ;
2011-03-06 15:00:30 +08:00
static php_rfc1867_get_detect_order_t php_rfc1867_get_detect_order = NULL ;
static php_rfc1867_set_input_encoding_t php_rfc1867_set_input_encoding = NULL ;
static php_rfc1867_getword_t php_rfc1867_getword = php_ap_getword ;
static php_rfc1867_getword_conf_t php_rfc1867_getword_conf = php_ap_getword_conf ;
2010-12-08 19:27:34 +08:00
static php_rfc1867_basename_t php_rfc1867_basename = NULL ;
PHPAPI int ( * php_rfc1867_callback ) ( unsigned int event , void * event_data , void * * extra TSRMLS_DC ) = NULL ;
1999-06-13 01:50:39 +08:00
2014-08-26 02:22:49 +08:00
static void safe_php_register_variable ( char * var , char * strval , size_t val_len , zval * track_vars_array , zend_bool override_protection TSRMLS_DC ) ;
2002-05-11 19:58:16 +08:00
2000-04-03 05:27:32 +08:00
/* The longest property name we use in an uploaded file array */
2000-04-03 06:15:14 +08:00
# define MAX_SIZE_OF_INDEX sizeof("[tmp_name]")
2000-04-03 05:27:32 +08:00
2003-01-07 07:51:28 +08:00
/* The longest anonymous name */
# define MAX_SIZE_ANONNAME 33
2001-11-11 08:45:31 +08:00
/* Errors */
2013-06-11 05:20:18 +08:00
# define UPLOAD_ERROR_OK 0 /* File upload successful */
2002-07-12 09:49:58 +08:00
# define UPLOAD_ERROR_A 1 /* Uploaded file exceeded upload_max_filesize */
# define UPLOAD_ERROR_B 2 /* Uploaded file exceeded MAX_FILE_SIZE */
# define UPLOAD_ERROR_C 3 /* Partially uploaded */
# define UPLOAD_ERROR_D 4 /* No file uploaded */
2004-11-11 08:38:04 +08:00
# define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
2005-07-14 04:44:08 +08:00
# define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
2006-07-23 00:38:29 +08:00
# define UPLOAD_ERROR_X 8 /* File upload stopped by extension */
2002-07-12 09:49:58 +08:00
2010-12-02 17:40:53 +08:00
void php_rfc1867_register_constants ( TSRMLS_D ) /* { { { */
2002-07-12 09:49:58 +08:00
{
2014-08-26 01:24:55 +08:00
REGISTER_MAIN_LONG_CONSTANT ( " UPLOAD_ERR_OK " , UPLOAD_ERROR_OK , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " UPLOAD_ERR_INI_SIZE " , UPLOAD_ERROR_A , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " UPLOAD_ERR_FORM_SIZE " , UPLOAD_ERROR_B , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " UPLOAD_ERR_PARTIAL " , UPLOAD_ERROR_C , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " UPLOAD_ERR_NO_FILE " , UPLOAD_ERROR_D , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " UPLOAD_ERR_NO_TMP_DIR " , UPLOAD_ERROR_E , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " UPLOAD_ERR_CANT_WRITE " , UPLOAD_ERROR_F , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " UPLOAD_ERR_EXTENSION " , UPLOAD_ERROR_X , CONST_CS | CONST_PERSISTENT ) ;
2002-07-12 09:49:58 +08:00
}
2009-12-30 02:59:58 +08:00
/* }}} */
2001-10-27 13:26:24 +08:00
2009-12-30 02:59:58 +08:00
static void normalize_protected_variable ( char * varname TSRMLS_DC ) /* { { { */
2002-10-07 19:23:24 +08:00
{
2009-12-30 02:59:58 +08:00
char * s = varname , * index = NULL , * indexend = NULL , * p ;
2002-10-07 19:23:24 +08:00
/* overjump leading space */
while ( * s = = ' ' ) {
s + + ;
}
2009-12-30 02:59:58 +08:00
2002-10-07 19:23:24 +08:00
/* and remove it */
if ( s ! = varname ) {
2003-11-03 19:46:33 +08:00
memmove ( varname , s , strlen ( s ) + 1 ) ;
2002-10-07 19:23:24 +08:00
}
2009-12-30 02:59:58 +08:00
for ( p = varname ; * p & & * p ! = ' [ ' ; p + + ) {
2002-11-23 03:34:17 +08:00
switch ( * p ) {
case ' ' :
case ' . ' :
2009-12-30 02:59:58 +08:00
* p = ' _ ' ;
2002-11-23 03:34:17 +08:00
break ;
}
}
2002-10-07 19:23:24 +08:00
/* find index */
index = strchr ( varname , ' [ ' ) ;
if ( index ) {
index + + ;
2009-12-30 02:59:58 +08:00
s = index ;
2002-10-07 19:23:24 +08:00
} else {
return ;
}
/* done? */
while ( index ) {
while ( * index = = ' ' | | * index = = ' \r ' | | * index = = ' \n ' | | * index = = ' \t ' ) {
index + + ;
}
indexend = strchr ( index , ' ] ' ) ;
indexend = indexend ? indexend + 1 : index + strlen ( index ) ;
2009-12-30 02:59:58 +08:00
2002-10-07 19:23:24 +08:00
if ( s ! = index ) {
2003-11-03 19:46:33 +08:00
memmove ( s , index , strlen ( index ) + 1 ) ;
2002-10-07 19:23:24 +08:00
s + = indexend - index ;
} else {
s = indexend ;
}
if ( * s = = ' [ ' ) {
s + + ;
index = s ;
} else {
index = NULL ;
2009-12-30 02:59:58 +08:00
}
2002-10-07 19:23:24 +08:00
}
2008-09-23 23:18:26 +08:00
* s = ' \0 ' ;
2002-10-07 19:23:24 +08:00
}
2010-12-02 17:40:53 +08:00
/* }}} */
2002-10-07 19:23:24 +08:00
2010-12-02 17:40:53 +08:00
static void add_protected_variable ( char * varname TSRMLS_DC ) /* { { { */
2000-09-05 03:07:50 +08:00
{
2002-10-07 19:23:24 +08:00
normalize_protected_variable ( varname TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
zend_hash_str_add_empty_element ( & PG ( rfc1867_protected_variables ) , varname , strlen ( varname ) ) ;
2000-09-05 03:07:50 +08:00
}
2010-12-02 17:40:53 +08:00
/* }}} */
2000-09-05 03:07:50 +08:00
2009-12-30 02:59:58 +08:00
static zend_bool is_protected_variable ( char * varname TSRMLS_DC ) /* { { { */
2000-09-05 03:07:50 +08:00
{
2002-10-07 19:23:24 +08:00
normalize_protected_variable ( varname TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
return zend_hash_str_exists ( & PG ( rfc1867_protected_variables ) , varname , strlen ( varname ) ) ;
2000-09-05 03:07:50 +08:00
}
2009-12-30 02:59:58 +08:00
/* }}} */
2000-09-05 03:07:50 +08:00
2014-08-26 02:22:49 +08:00
static void safe_php_register_variable ( char * var , char * strval , size_t val_len , zval * track_vars_array , zend_bool override_protection TSRMLS_DC ) /* { { { */
2000-09-05 03:07:50 +08:00
{
2001-07-28 19:36:37 +08:00
if ( override_protection | | ! is_protected_variable ( var TSRMLS_CC ) ) {
2006-07-28 01:04:15 +08:00
php_register_variable_safe ( var , strval , val_len , track_vars_array TSRMLS_CC ) ;
2000-09-05 03:07:50 +08:00
}
}
2010-12-02 17:40:53 +08:00
/* }}} */
2000-09-05 03:07:50 +08:00
2010-12-02 17:40:53 +08:00
static void safe_php_register_variable_ex ( char * var , zval * val , zval * track_vars_array , zend_bool override_protection TSRMLS_DC ) /* { { { */
2000-09-05 03:07:50 +08:00
{
2001-07-28 19:36:37 +08:00
if ( override_protection | | ! is_protected_variable ( var TSRMLS_CC ) ) {
php_register_variable_ex ( var , val , track_vars_array TSRMLS_CC ) ;
2000-09-05 03:07:50 +08:00
}
}
2010-12-02 17:40:53 +08:00
/* }}} */
2000-09-05 03:07:50 +08:00
2010-12-02 17:40:53 +08:00
static void register_http_post_files_variable ( char * strvar , char * val , zval * http_post_files , zend_bool override_protection TSRMLS_DC ) /* { { { */
2000-02-20 04:12:26 +08:00
{
2006-07-28 01:04:15 +08:00
safe_php_register_variable ( strvar , val , strlen ( val ) , http_post_files , override_protection TSRMLS_CC ) ;
2000-02-20 04:12:26 +08:00
}
2010-12-02 17:40:53 +08:00
/* }}} */
2000-02-20 04:12:26 +08:00
2009-12-30 02:59:58 +08:00
static void register_http_post_files_variable_ex ( char * var , zval * val , zval * http_post_files , zend_bool override_protection TSRMLS_DC ) /* { { { */
2000-02-20 04:12:26 +08:00
{
2001-07-28 19:36:37 +08:00
safe_php_register_variable_ex ( var , val , http_post_files , override_protection TSRMLS_CC ) ;
2000-02-20 04:12:26 +08:00
}
2010-12-02 17:40:53 +08:00
/* }}} */
2000-02-20 04:12:26 +08:00
2014-03-05 14:40:49 +08:00
static int unlink_filename ( zval * el TSRMLS_DC ) /* { { { */
2000-09-09 19:41:14 +08:00
{
2014-03-05 14:40:49 +08:00
char * filename = ( char * ) Z_PTR_P ( el ) ;
VCWD_UNLINK ( filename ) ;
2000-09-09 19:41:14 +08:00
return 0 ;
}
2009-12-30 02:59:58 +08:00
/* }}} */
2000-09-09 19:41:14 +08:00
2014-03-05 14:43:20 +08:00
static void free_filename ( zval * el ) {
char * filename = ( char * ) Z_PTR_P ( el ) ;
efree ( filename ) ;
}
2009-12-30 02:59:58 +08:00
void destroy_uploaded_files_hash ( TSRMLS_D ) /* { { { */
2000-09-09 19:41:14 +08:00
{
2014-03-05 14:40:49 +08:00
zend_hash_apply ( SG ( rfc1867_uploaded_files ) , unlink_filename TSRMLS_CC ) ;
2000-09-09 19:41:14 +08:00
zend_hash_destroy ( SG ( rfc1867_uploaded_files ) ) ;
FREE_HASHTABLE ( SG ( rfc1867_uploaded_files ) ) ;
}
2009-12-30 02:59:58 +08:00
/* }}} */
2000-09-09 19:41:14 +08:00
2010-12-02 17:40:53 +08:00
/* {{{ Following code is based on apache_multipart_buffer.c from libapreq-0.33 package. */
1999-06-13 01:50:39 +08:00
2001-10-27 13:26:24 +08:00
# define FILLUNIT (1024 * 5)
2000-09-05 03:07:50 +08:00
2001-10-27 13:26:24 +08:00
typedef struct {
2000-09-09 05:56:47 +08:00
2001-10-27 13:26:24 +08:00
/* read buffer */
char * buffer ;
char * buf_begin ;
int bufsize ;
int bytes_in_buffer ;
2000-02-20 04:12:26 +08:00
2001-10-27 13:26:24 +08:00
/* boundary info */
char * boundary ;
char * boundary_next ;
int boundary_next_len ;
2001-09-03 10:31:56 +08:00
2011-03-06 15:00:30 +08:00
const zend_encoding * input_encoding ;
const zend_encoding * * detect_order ;
size_t detect_order_size ;
2001-10-27 13:26:24 +08:00
} multipart_buffer ;
1999-06-13 01:50:39 +08:00
2001-10-27 13:26:24 +08:00
typedef struct {
char * key ;
char * value ;
} mime_header_entry ;
2000-02-13 01:37:11 +08:00
2001-10-27 13:26:24 +08:00
/*
2009-12-30 02:59:58 +08:00
* Fill up the buffer with client data .
2009-12-30 03:25:09 +08:00
* Returns number of bytes added to buffer .
2009-12-30 02:59:58 +08:00
*/
2001-10-27 13:26:24 +08:00
static int fill_buffer ( multipart_buffer * self TSRMLS_DC )
{
2002-06-05 21:35:34 +08:00
int bytes_to_read , total_read = 0 , actual_read = 0 ;
2000-02-20 04:12:26 +08:00
2001-10-27 13:26:24 +08:00
/* shift the existing data if necessary */
2001-11-25 00:05:22 +08:00
if ( self - > bytes_in_buffer > 0 & & self - > buf_begin ! = self - > buffer ) {
2001-10-27 13:26:24 +08:00
memmove ( self - > buffer , self - > buf_begin , self - > bytes_in_buffer ) ;
}
2000-07-30 19:22:18 +08:00
2001-10-27 13:26:24 +08:00
self - > buf_begin = self - > buffer ;
2000-09-09 19:41:14 +08:00
2001-10-27 13:26:24 +08:00
/* calculate the free space in the buffer */
bytes_to_read = self - > bufsize - self - > bytes_in_buffer ;
2000-04-03 05:27:32 +08:00
2001-10-27 13:26:24 +08:00
/* read the required number of bytes */
2002-06-05 21:35:34 +08:00
while ( bytes_to_read > 0 ) {
2000-09-09 19:41:14 +08:00
2001-10-27 13:26:24 +08:00
char * buf = self - > buffer + self - > bytes_in_buffer ;
2000-02-20 04:12:26 +08:00
2014-10-27 23:38:05 +08:00
actual_read = ( int ) sapi_module . read_post ( buf , bytes_to_read TSRMLS_CC ) ;
2000-02-20 04:12:26 +08:00
2001-10-27 13:26:24 +08:00
/* update the buffer length */
2001-11-25 00:05:22 +08:00
if ( actual_read > 0 ) {
2001-10-27 13:26:24 +08:00
self - > bytes_in_buffer + = actual_read ;
2001-12-05 08:44:17 +08:00
SG ( read_post_bytes ) + = actual_read ;
2002-06-05 21:35:34 +08:00
total_read + = actual_read ;
bytes_to_read - = actual_read ;
} else {
break ;
1999-06-13 01:50:39 +08:00
}
}
2001-10-27 13:26:24 +08:00
2002-06-05 21:35:34 +08:00
return total_read ;
1999-06-13 01:50:39 +08:00
}
2001-10-27 13:26:24 +08:00
/* eof if we are out of bytes, or if we hit the final boundary */
static int multipart_buffer_eof ( multipart_buffer * self TSRMLS_DC )
{
2001-11-25 00:05:22 +08:00
if ( ( self - > bytes_in_buffer = = 0 & & fill_buffer ( self TSRMLS_CC ) < 1 ) ) {
2001-10-27 13:26:24 +08:00
return 1 ;
} else {
return 0 ;
}
}
/* create new multipart_buffer structure */
2011-03-06 15:00:30 +08:00
static multipart_buffer * multipart_buffer_new ( char * boundary , int boundary_len TSRMLS_DC )
2001-10-27 13:26:24 +08:00
{
multipart_buffer * self = ( multipart_buffer * ) ecalloc ( 1 , sizeof ( multipart_buffer ) ) ;
int minsize = boundary_len + 6 ;
2001-11-25 00:05:22 +08:00
if ( minsize < FILLUNIT ) minsize = FILLUNIT ;
2001-10-27 13:26:24 +08:00
self - > buffer = ( char * ) ecalloc ( 1 , minsize + 1 ) ;
self - > bufsize = minsize ;
2007-02-24 10:17:47 +08:00
spprintf ( & self - > boundary , 0 , " --%s " , boundary ) ;
2009-12-30 02:59:58 +08:00
2014-10-27 23:38:05 +08:00
self - > boundary_next_len = ( int ) spprintf ( & self - > boundary_next , 0 , " \n --%s " , boundary ) ;
2001-10-27 13:26:24 +08:00
self - > buf_begin = self - > buffer ;
self - > bytes_in_buffer = 0 ;
2011-03-06 15:00:30 +08:00
if ( php_rfc1867_encoding_translation ( TSRMLS_C ) ) {
php_rfc1867_get_detect_order ( & self - > detect_order , & self - > detect_order_size TSRMLS_CC ) ;
} else {
self - > detect_order = NULL ;
self - > detect_order_size = 0 ;
}
self - > input_encoding = NULL ;
2001-10-27 13:26:24 +08:00
return self ;
}
1999-06-13 01:50:39 +08:00
2001-09-03 10:31:56 +08:00
/*
2009-12-30 02:59:58 +08:00
* Gets the next CRLF terminated line from the input buffer .
* If it doesn ' t find a CRLF , and the buffer isn ' t completely full , returns
* NULL ; otherwise , returns the beginning of the null - terminated line ,
* minus the CRLF .
*
* Note that we really just look for LF terminated lines . This works
* around a bug in internet explorer for the macintosh which sends mime
* boundaries that are only LF terminated when you use an image submit
* button in a multipart / form - data form .
2001-09-03 10:31:56 +08:00
*/
2001-10-27 13:26:24 +08:00
static char * next_line ( multipart_buffer * self )
2001-09-03 10:31:56 +08:00
{
2001-10-27 13:26:24 +08:00
/* look for LF in the data */
char * line = self - > buf_begin ;
char * ptr = memchr ( self - > buf_begin , ' \n ' , self - > bytes_in_buffer ) ;
2001-11-25 00:05:22 +08:00
if ( ptr ) { /* LF found */
2001-10-27 13:26:24 +08:00
/* terminate the string, remove CRLF */
2001-11-25 00:05:22 +08:00
if ( ( ptr - line ) > 0 & & * ( ptr - 1 ) = = ' \r ' ) {
2001-10-27 13:26:24 +08:00
* ( ptr - 1 ) = 0 ;
} else {
* ptr = 0 ;
}
/* bump the pointer */
self - > buf_begin = ptr + 1 ;
self - > bytes_in_buffer - = ( self - > buf_begin - line ) ;
2009-12-30 02:59:58 +08:00
2001-10-27 13:26:24 +08:00
} else { /* no LF found */
/* buffer isn't completely full, fail */
2001-11-25 00:05:22 +08:00
if ( self - > bytes_in_buffer < self - > bufsize ) {
2001-10-27 13:26:24 +08:00
return NULL ;
}
/* return entire buffer as a partial line */
line [ self - > bufsize ] = 0 ;
self - > buf_begin = ptr ;
self - > bytes_in_buffer = 0 ;
}
return line ;
}
2009-12-30 03:25:09 +08:00
/* Returns the next CRLF terminated line from the client */
2001-10-27 13:26:24 +08:00
static char * get_line ( multipart_buffer * self TSRMLS_DC )
{
char * ptr = next_line ( self ) ;
2001-11-25 00:05:22 +08:00
if ( ! ptr ) {
2001-10-27 13:26:24 +08:00
fill_buffer ( self TSRMLS_CC ) ;
ptr = next_line ( self ) ;
}
return ptr ;
}
/* Free header entry */
static void php_free_hdr_entry ( mime_header_entry * h )
{
2001-11-25 00:05:22 +08:00
if ( h - > key ) {
efree ( h - > key ) ;
}
if ( h - > value ) {
efree ( h - > value ) ;
}
2001-10-27 13:26:24 +08:00
}
/* finds a boundary */
static int find_boundary ( multipart_buffer * self , char * boundary TSRMLS_DC )
{
char * line ;
/* loop thru lines */
while ( ( line = get_line ( self TSRMLS_CC ) ) )
{
/* finished if we found the boundary */
2001-11-25 00:05:22 +08:00
if ( ! strcmp ( line , boundary ) ) {
2001-10-27 13:26:24 +08:00
return 1 ;
}
}
/* didn't find the boundary */
return 0 ;
}
/* parse headers */
static int multipart_buffer_headers ( multipart_buffer * self , zend_llist * header TSRMLS_DC )
{
char * line ;
2013-08-15 11:36:50 +08:00
mime_header_entry prev_entry = { 0 } , entry ;
2001-10-27 13:26:24 +08:00
int prev_len , cur_len ;
2009-12-30 02:59:58 +08:00
2001-10-27 13:26:24 +08:00
/* didn't find boundary, abort */
2001-11-25 00:05:22 +08:00
if ( ! find_boundary ( self , self - > boundary TSRMLS_CC ) ) {
2001-10-27 13:26:24 +08:00
return 0 ;
}
/* get lines of text, or CRLF_CRLF */
2012-04-03 09:54:57 +08:00
while ( ( line = get_line ( self TSRMLS_CC ) ) & & line [ 0 ] ! = ' \0 ' )
2001-10-27 13:26:24 +08:00
{
/* add header to table */
char * key = line ;
2002-06-05 21:35:34 +08:00
char * value = NULL ;
2009-12-30 02:59:58 +08:00
2011-03-06 15:00:30 +08:00
if ( php_rfc1867_encoding_translation ( TSRMLS_C ) ) {
self - > input_encoding = zend_multibyte_encoding_detector ( line , strlen ( line ) , self - > detect_order , self - > detect_order_size TSRMLS_CC ) ;
}
2002-06-05 21:35:34 +08:00
/* space in the beginning means same header */
if ( ! isspace ( line [ 0 ] ) ) {
value = strchr ( line , ' : ' ) ;
}
2001-10-27 13:26:24 +08:00
2001-11-25 00:05:22 +08:00
if ( value ) {
2001-10-27 13:26:24 +08:00
* value = 0 ;
do { value + + ; } while ( isspace ( * value ) ) ;
entry . value = estrdup ( value ) ;
entry . key = estrdup ( key ) ;
2002-07-16 00:37:15 +08:00
} else if ( zend_llist_count ( header ) ) { /* If no ':' on the line, add to previous line */
2001-10-27 13:26:24 +08:00
2014-10-27 23:38:05 +08:00
prev_len = ( int ) strlen ( prev_entry . value ) ;
cur_len = ( int ) strlen ( line ) ;
2001-10-27 13:26:24 +08:00
entry . value = emalloc ( prev_len + cur_len + 1 ) ;
memcpy ( entry . value , prev_entry . value , prev_len ) ;
memcpy ( entry . value + prev_len , line , cur_len ) ;
entry . value [ cur_len + prev_len ] = ' \0 ' ;
entry . key = estrdup ( prev_entry . key ) ;
2009-12-30 02:59:58 +08:00
2002-06-05 21:35:34 +08:00
zend_llist_remove_tail ( header ) ;
2002-06-05 19:28:33 +08:00
} else {
continue ;
2001-10-27 13:26:24 +08:00
}
zend_llist_add_element ( header , & entry ) ;
prev_entry = entry ;
}
return 1 ;
2001-09-03 10:31:56 +08:00
}
2001-10-27 13:26:24 +08:00
static char * php_mime_get_hdr_value ( zend_llist header , char * key )
{
mime_header_entry * entry ;
if ( key = = NULL ) {
return NULL ;
}
2009-12-30 02:59:58 +08:00
2001-10-27 13:26:24 +08:00
entry = zend_llist_get_first ( & header ) ;
2002-04-23 08:14:08 +08:00
while ( entry ) {
2001-11-25 00:05:22 +08:00
if ( ! strcasecmp ( entry - > key , key ) ) {
2001-10-27 13:26:24 +08:00
return entry - > value ;
}
2002-04-23 08:14:08 +08:00
entry = zend_llist_get_next ( & header ) ;
}
2009-12-30 02:59:58 +08:00
2001-10-27 13:26:24 +08:00
return NULL ;
}
2011-03-06 15:00:30 +08:00
static char * php_ap_getword ( const zend_encoding * encoding , char * * line , char stop TSRMLS_DC )
2001-10-27 13:26:24 +08:00
{
2001-12-16 21:34:52 +08:00
char * pos = * line , quote ;
2001-10-27 13:26:24 +08:00
char * res ;
2001-12-16 21:34:52 +08:00
while ( * pos & & * pos ! = stop ) {
if ( ( quote = * pos ) = = ' " ' | | quote = = ' \' ' ) {
+ + pos ;
while ( * pos & & * pos ! = quote ) {
if ( * pos = = ' \\ ' & & pos [ 1 ] & & pos [ 1 ] = = quote ) {
pos + = 2 ;
} else {
+ + pos ;
}
}
2002-06-07 16:00:12 +08:00
if ( * pos ) {
+ + pos ;
}
2001-12-16 21:34:52 +08:00
} else + + pos ;
}
if ( * pos = = ' \0 ' ) {
2001-10-27 13:26:24 +08:00
res = estrdup ( * line ) ;
* line + = strlen ( * line ) ;
return res ;
}
res = estrndup ( * line , pos - * line ) ;
while ( * pos = = stop ) {
+ + pos ;
}
* line = pos ;
return res ;
}
2011-03-06 15:00:30 +08:00
static char * substring_conf ( char * start , int len , char quote )
2001-10-27 13:26:24 +08:00
{
2010-12-08 19:27:34 +08:00
char * result = emalloc ( len + 1 ) ;
2001-10-27 13:26:24 +08:00
char * resp = result ;
int i ;
2010-12-08 19:27:34 +08:00
for ( i = 0 ; i < len & & start [ i ] ! = quote ; + + i ) {
2001-10-27 13:26:24 +08:00
if ( start [ i ] = = ' \\ ' & & ( start [ i + 1 ] = = ' \\ ' | | ( quote & & start [ i + 1 ] = = quote ) ) ) {
* resp + + = start [ + + i ] ;
} else {
2002-10-24 10:59:01 +08:00
* resp + + = start [ i ] ;
2001-10-27 13:26:24 +08:00
}
}
2008-09-23 23:18:26 +08:00
* resp = ' \0 ' ;
2001-10-27 13:26:24 +08:00
return result ;
}
2011-03-06 15:00:30 +08:00
static char * php_ap_getword_conf ( const zend_encoding * encoding , char * str TSRMLS_DC )
2001-10-27 13:26:24 +08:00
{
while ( * str & & isspace ( * str ) ) {
+ + str ;
}
if ( ! * str ) {
2001-12-16 21:34:52 +08:00
return estrdup ( " " ) ;
2001-10-27 13:26:24 +08:00
}
2010-12-08 19:27:34 +08:00
if ( * str = = ' " ' | | * str = = ' \' ' ) {
char quote = * str ;
2001-10-27 13:26:24 +08:00
2010-12-08 19:27:34 +08:00
str + + ;
2014-10-27 23:38:05 +08:00
return substring_conf ( str , ( int ) strlen ( str ) , quote ) ;
2001-10-27 13:26:24 +08:00
} else {
2010-12-08 19:27:34 +08:00
char * strend = str ;
2001-10-27 13:26:24 +08:00
while ( * strend & & ! isspace ( * strend ) ) {
+ + strend ;
}
2011-03-06 15:00:30 +08:00
return substring_conf ( str , strend - str , 0 ) ;
2001-10-27 13:26:24 +08:00
}
}
2011-03-06 15:00:30 +08:00
static char * php_ap_basename ( const zend_encoding * encoding , char * path TSRMLS_DC )
{
char * s = strrchr ( path , ' \\ ' ) ;
2011-06-12 23:15:44 +08:00
char * s2 = strrchr ( path , ' / ' ) ;
2012-01-02 07:54:25 +08:00
2011-06-12 23:15:44 +08:00
if ( s & & s2 ) {
if ( s > s2 ) {
+ + s ;
2011-03-06 15:00:30 +08:00
} else {
2011-06-12 23:15:44 +08:00
s = + + s2 ;
2011-03-06 15:00:30 +08:00
}
2011-06-12 23:15:44 +08:00
return s ;
} else if ( s ) {
return + + s ;
} else if ( s2 ) {
return + + s2 ;
2011-03-06 15:00:30 +08:00
}
2011-06-12 23:15:44 +08:00
return path ;
2011-03-06 15:00:30 +08:00
}
2001-10-27 13:26:24 +08:00
/*
2009-12-30 02:59:58 +08:00
* Search for a string in a fixed - length byte string .
* If partial is true , partial matches are allowed at the end of the buffer .
* Returns NULL if not found , or a pointer to the start of the first match .
2009-12-30 03:25:09 +08:00
*/
2001-10-27 13:26:24 +08:00
static void * php_ap_memstr ( char * haystack , int haystacklen , char * needle , int needlen , int partial )
{
int len = haystacklen ;
char * ptr = haystack ;
/* iterate through first character matches */
while ( ( ptr = memchr ( ptr , needle [ 0 ] , len ) ) ) {
/* calculate length after match */
len = haystacklen - ( ptr - ( char * ) haystack ) ;
/* done if matches up to capacity of buffer */
2001-11-25 00:05:22 +08:00
if ( memcmp ( needle , ptr , needlen < len ? needlen : len ) = = 0 & & ( partial | | len > = needlen ) ) {
2001-10-27 13:26:24 +08:00
break ;
}
/* next character */
ptr + + ; len - - ;
}
return ptr ;
}
/* read until a boundary condition */
2014-08-26 02:22:49 +08:00
static int multipart_buffer_read ( multipart_buffer * self , char * buf , size_t bytes , int * end TSRMLS_DC )
2001-10-27 13:26:24 +08:00
{
2014-08-26 02:22:49 +08:00
size_t len , max ;
2001-10-27 13:26:24 +08:00
char * bound ;
/* fill buffer if needed */
2001-11-25 00:05:22 +08:00
if ( bytes > self - > bytes_in_buffer ) {
2001-10-27 13:26:24 +08:00
fill_buffer ( self TSRMLS_CC ) ;
}
/* look for a potential boundary match, only read data up to that point */
2001-11-25 00:05:22 +08:00
if ( ( bound = php_ap_memstr ( self - > buf_begin , self - > bytes_in_buffer , self - > boundary_next , self - > boundary_next_len , 1 ) ) ) {
2001-10-27 13:26:24 +08:00
max = bound - self - > buf_begin ;
2005-07-14 04:44:08 +08:00
if ( end & & php_ap_memstr ( self - > buf_begin , self - > bytes_in_buffer , self - > boundary_next , self - > boundary_next_len , 0 ) ) {
* end = 1 ;
}
2001-10-27 13:26:24 +08:00
} else {
max = self - > bytes_in_buffer ;
}
/* maximum number of bytes we are reading */
len = max < bytes - 1 ? max : bytes - 1 ;
/* if we read any data... */
2001-11-25 00:05:22 +08:00
if ( len > 0 ) {
2001-10-27 13:26:24 +08:00
/* copy the data */
memcpy ( buf , self - > buf_begin , len ) ;
buf [ len ] = 0 ;
2001-11-25 00:05:22 +08:00
if ( bound & & len > 0 & & buf [ len - 1 ] = = ' \r ' ) {
2001-10-27 13:26:24 +08:00
buf [ - - len ] = 0 ;
}
/* update the buffer */
2014-10-27 23:38:05 +08:00
self - > bytes_in_buffer - = ( int ) len ;
2001-10-27 13:26:24 +08:00
self - > buf_begin + = len ;
}
2014-10-27 23:38:05 +08:00
return ( int ) len ;
2001-10-27 13:26:24 +08:00
}
/*
XXX : this is horrible memory - usage - wise , but we only expect
to do this on small pieces of form data .
*/
2014-08-26 02:22:49 +08:00
static char * multipart_buffer_read_body ( multipart_buffer * self , size_t * len TSRMLS_DC )
2001-10-27 13:26:24 +08:00
{
char buf [ FILLUNIT ] , * out = NULL ;
int total_bytes = 0 , read_bytes = 0 ;
2005-07-14 04:44:08 +08:00
while ( ( read_bytes = multipart_buffer_read ( self , buf , sizeof ( buf ) , NULL TSRMLS_CC ) ) ) {
2001-12-14 02:12:58 +08:00
out = erealloc ( out , total_bytes + read_bytes + 1 ) ;
memcpy ( out + total_bytes , buf , read_bytes ) ;
2001-10-27 13:26:24 +08:00
total_bytes + = read_bytes ;
}
2009-12-30 03:25:09 +08:00
if ( out ) {
out [ total_bytes ] = ' \0 ' ;
}
2006-07-28 01:04:15 +08:00
* len = total_bytes ;
2001-10-27 13:26:24 +08:00
return out ;
}
2009-12-30 03:25:09 +08:00
/* }}} */
2001-10-27 13:26:24 +08:00
/*
* The combined READER / HANDLER
*
*/
2010-12-02 17:40:53 +08:00
SAPI_API SAPI_POST_HANDLER_FUNC ( rfc1867_post_handler ) /* { { { */
1999-05-26 06:28:24 +08:00
{
2009-12-30 02:59:58 +08:00
char * boundary , * s = NULL , * boundary_end = NULL , * start_arr = NULL , * array_index = NULL ;
char * temp_filename = NULL , * lbuf = NULL , * abuf = NULL ;
2013-06-28 14:32:10 +08:00
int boundary_len = 0 , cancel_upload = 0 , is_arr_upload = 0 , array_len = 0 ;
2013-07-23 00:03:11 +08:00
int64_t total_bytes = 0 , max_file_size = 0 ;
2013-06-28 14:32:10 +08:00
int skip_upload = 0 , anonindex = 0 , is_anonymous ;
2009-12-30 02:59:58 +08:00
HashTable * uploaded_files = NULL ;
2001-10-27 13:26:24 +08:00
multipart_buffer * mbuff ;
2000-02-18 04:23:59 +08:00
zval * array_ptr = ( zval * ) arg ;
2009-12-30 03:25:09 +08:00
int fd = - 1 ;
2001-10-27 13:26:24 +08:00
zend_llist header ;
2006-07-23 00:38:29 +08:00
void * event_extra_data = NULL ;
2010-08-17 20:49:19 +08:00
unsigned int llen = 0 ;
2009-11-16 21:34:57 +08:00
int upload_cnt = INI_INT ( " max_file_uploads " ) ;
2011-03-06 15:00:30 +08:00
const zend_encoding * internal_encoding = zend_multibyte_get_internal_encoding ( TSRMLS_C ) ;
php_rfc1867_getword_t getword ;
php_rfc1867_getword_conf_t getword_conf ;
php_rfc1867_basename_t _basename ;
2014-08-26 01:24:55 +08:00
zend_long count = 0 ;
2011-03-06 15:00:30 +08:00
if ( php_rfc1867_encoding_translation ( TSRMLS_C ) & & internal_encoding ) {
getword = php_rfc1867_getword ;
getword_conf = php_rfc1867_getword_conf ;
_basename = php_rfc1867_basename ;
} else {
getword = php_ap_getword ;
getword_conf = php_ap_getword_conf ;
_basename = php_ap_basename ;
}
2001-10-27 13:26:24 +08:00
2009-11-18 04:33:51 +08:00
if ( SG ( post_max_size ) > 0 & & SG ( request_info ) . content_length > SG ( post_max_size ) ) {
2014-08-26 02:22:49 +08:00
sapi_module . sapi_error ( E_WARNING , " POST Content-Length of " ZEND_LONG_FMT " bytes exceeds the limit of " ZEND_LONG_FMT " bytes " , SG ( request_info ) . content_length , SG ( post_max_size ) ) ;
2001-09-03 10:31:56 +08:00
return ;
}
2001-10-27 13:26:24 +08:00
/* Get the boundary */
1999-05-26 06:28:24 +08:00
boundary = strstr ( content_type_dup , " boundary " ) ;
2009-12-29 23:57:54 +08:00
if ( ! boundary ) {
2014-10-27 23:38:05 +08:00
int content_type_len = ( int ) strlen ( content_type_dup ) ;
2009-12-29 23:57:54 +08:00
char * content_type_lcase = estrndup ( content_type_dup , content_type_len ) ;
php_strtolower ( content_type_lcase , content_type_len ) ;
boundary = strstr ( content_type_lcase , " boundary " ) ;
if ( boundary ) {
boundary = content_type_dup + ( boundary - content_type_lcase ) ;
}
efree ( content_type_lcase ) ;
}
2009-12-30 02:59:58 +08:00
if ( ! boundary | | ! ( boundary = strchr ( boundary , ' = ' ) ) ) {
2001-10-27 13:26:24 +08:00
sapi_module . sapi_error ( E_WARNING , " Missing boundary in multipart/form-data POST data " ) ;
1999-05-26 06:28:24 +08:00
return ;
}
2002-08-17 03:34:43 +08:00
1999-05-26 06:28:24 +08:00
boundary + + ;
2014-10-27 23:38:05 +08:00
boundary_len = ( int ) strlen ( boundary ) ;
1999-05-26 06:28:24 +08:00
2002-08-17 19:48:21 +08:00
if ( boundary [ 0 ] = = ' " ' ) {
boundary + + ;
boundary_end = strchr ( boundary , ' " ' ) ;
2009-12-30 02:59:58 +08:00
if ( ! boundary_end ) {
2001-12-14 02:12:58 +08:00
sapi_module . sapi_error ( E_WARNING , " Invalid boundary in multipart/form-data POST data " ) ;
return ;
}
2002-08-17 19:31:06 +08:00
} else {
/* search for the end of the boundary */
2011-09-08 00:19:09 +08:00
boundary_end = strpbrk ( boundary , " ,; " ) ;
2002-08-17 19:48:21 +08:00
}
if ( boundary_end ) {
boundary_end [ 0 ] = ' \0 ' ;
boundary_len = boundary_end - boundary ;
2000-10-21 07:40:07 +08:00
}
2001-10-27 13:26:24 +08:00
/* Initialize the buffer */
2011-03-06 15:06:55 +08:00
if ( ! ( mbuff = multipart_buffer_new ( boundary , boundary_len TSRMLS_CC ) ) ) {
2001-10-27 13:26:24 +08:00
sapi_module . sapi_error ( E_WARNING , " Unable to initialize the input buffer " ) ;
return ;
}
/* Initialize $_FILES[] */
2014-04-21 22:25:34 +08:00
zend_hash_init ( & PG ( rfc1867_protected_variables ) , 8 , NULL , NULL , 0 ) ;
2001-10-27 13:26:24 +08:00
2004-07-10 15:46:17 +08:00
ALLOC_HASHTABLE ( uploaded_files ) ;
2014-04-21 22:25:34 +08:00
zend_hash_init ( uploaded_files , 8 , NULL , free_filename , 0 ) ;
2004-07-10 15:46:17 +08:00
SG ( rfc1867_uploaded_files ) = uploaded_files ;
2001-10-27 13:26:24 +08:00
2014-02-10 14:04:30 +08:00
array_init ( & PG ( http_globals ) [ TRACK_VARS_FILES ] ) ;
2001-10-27 13:26:24 +08:00
zend_llist_init ( & header , sizeof ( mime_header_entry ) , ( llist_dtor_func_t ) php_free_hdr_entry , 0 ) ;
2006-07-23 00:38:29 +08:00
if ( php_rfc1867_callback ! = NULL ) {
multipart_event_start event_start ;
event_start . content_length = SG ( request_info ) . content_length ;
if ( php_rfc1867_callback ( MULTIPART_EVENT_START , & event_start , & event_extra_data TSRMLS_CC ) = = FAILURE ) {
goto fileupload_done ;
}
}
2001-10-27 13:26:24 +08:00
while ( ! multipart_buffer_eof ( mbuff TSRMLS_CC ) )
2001-09-03 10:31:56 +08:00
{
2001-10-27 13:26:24 +08:00
char buff [ FILLUNIT ] ;
2009-12-30 03:25:09 +08:00
char * cd = NULL , * param = NULL , * filename = NULL , * tmp = NULL ;
2009-12-30 02:59:58 +08:00
size_t blen = 0 , wlen = 0 ;
2014-08-16 17:16:11 +08:00
zend_off_t offset ;
2001-10-27 13:26:24 +08:00
zend_llist_clean ( & header ) ;
if ( ! multipart_buffer_headers ( mbuff , & header TSRMLS_CC ) ) {
2006-07-23 00:38:29 +08:00
goto fileupload_done ;
2001-10-27 13:26:24 +08:00
}
if ( ( cd = php_mime_get_hdr_value ( header , " Content-Disposition " ) ) ) {
2009-12-30 02:59:58 +08:00
char * pair = NULL ;
int end = 0 ;
2001-10-27 13:26:24 +08:00
while ( isspace ( * cd ) ) {
+ + cd ;
}
2011-03-06 15:00:30 +08:00
while ( * cd & & ( pair = getword ( mbuff - > input_encoding , & cd , ' ; ' TSRMLS_CC ) ) )
2001-10-27 13:26:24 +08:00
{
2009-12-30 02:59:58 +08:00
char * key = NULL , * word = pair ;
2001-10-27 13:26:24 +08:00
while ( isspace ( * cd ) ) {
+ + cd ;
}
if ( strchr ( pair , ' = ' ) ) {
2011-03-06 15:00:30 +08:00
key = getword ( mbuff - > input_encoding , & pair , ' = ' TSRMLS_CC ) ;
2009-12-30 02:59:58 +08:00
2003-05-24 05:40:45 +08:00
if ( ! strcasecmp ( key , " name " ) ) {
2001-12-17 05:59:13 +08:00
if ( param ) {
efree ( param ) ;
}
2011-03-06 15:00:30 +08:00
param = getword_conf ( mbuff - > input_encoding , pair TSRMLS_CC ) ;
if ( mbuff - > input_encoding & & internal_encoding ) {
unsigned char * new_param ;
size_t new_param_len ;
if ( ( size_t ) - 1 ! = zend_multibyte_encoding_converter ( & new_param , & new_param_len , ( unsigned char * ) param , strlen ( param ) , internal_encoding , mbuff - > input_encoding TSRMLS_CC ) ) {
efree ( param ) ;
param = ( char * ) new_param ;
2010-12-08 19:27:34 +08:00
}
}
2003-05-24 05:40:45 +08:00
} else if ( ! strcasecmp ( key , " filename " ) ) {
2001-12-17 05:59:13 +08:00
if ( filename ) {
efree ( filename ) ;
}
2011-03-06 15:00:30 +08:00
filename = getword_conf ( mbuff - > input_encoding , pair TSRMLS_CC ) ;
if ( mbuff - > input_encoding & & internal_encoding ) {
unsigned char * new_filename ;
size_t new_filename_len ;
if ( ( size_t ) - 1 ! = zend_multibyte_encoding_converter ( & new_filename , & new_filename_len , ( unsigned char * ) filename , strlen ( filename ) , internal_encoding , mbuff - > input_encoding TSRMLS_CC ) ) {
efree ( filename ) ;
filename = ( char * ) new_filename ;
2010-12-08 19:27:34 +08:00
}
}
2001-10-27 13:26:24 +08:00
}
}
2001-12-17 05:59:13 +08:00
if ( key ) {
efree ( key ) ;
}
2001-12-16 21:34:52 +08:00
efree ( word ) ;
2001-10-27 13:26:24 +08:00
}
2001-09-03 10:31:56 +08:00
2001-11-25 00:07:05 +08:00
/* Normal form variable, safe to read all data into memory */
2001-10-27 13:26:24 +08:00
if ( ! filename & & param ) {
2014-08-26 02:22:49 +08:00
size_t value_len ;
2006-07-28 01:04:15 +08:00
char * value = multipart_buffer_read_body ( mbuff , & value_len TSRMLS_CC ) ;
2014-08-26 02:22:49 +08:00
size_t new_val_len ; /* Dummy variable */
2001-10-27 13:26:24 +08:00
2001-12-17 05:59:13 +08:00
if ( ! value ) {
value = estrdup ( " " ) ;
2011-03-06 15:00:30 +08:00
value_len = 0 ;
2001-12-17 05:59:13 +08:00
}
2001-10-27 13:26:24 +08:00
2011-03-06 15:00:30 +08:00
if ( mbuff - > input_encoding & & internal_encoding ) {
unsigned char * new_value ;
size_t new_value_len ;
if ( ( size_t ) - 1 ! = zend_multibyte_encoding_converter ( & new_value , & new_value_len , ( unsigned char * ) value , value_len , internal_encoding , mbuff - > input_encoding TSRMLS_CC ) ) {
efree ( value ) ;
value = ( char * ) new_value ;
value_len = new_value_len ;
}
}
2012-02-14 16:58:52 +08:00
if ( + + count < = PG ( max_input_vars ) & & sapi_module . input_filter ( PARSE_POST , param , & value , value_len , & new_val_len TSRMLS_CC ) ) {
2006-07-23 00:38:29 +08:00
if ( php_rfc1867_callback ! = NULL ) {
multipart_event_formdata event_formdata ;
2008-09-07 01:18:40 +08:00
size_t newlength = new_val_len ;
2006-07-23 00:38:29 +08:00
event_formdata . post_bytes_processed = SG ( read_post_bytes ) ;
event_formdata . name = param ;
event_formdata . value = & value ;
event_formdata . length = new_val_len ;
event_formdata . newlength = & newlength ;
if ( php_rfc1867_callback ( MULTIPART_EVENT_FORMDATA , & event_formdata , & event_extra_data TSRMLS_CC ) = = FAILURE ) {
efree ( param ) ;
efree ( value ) ;
continue ;
}
new_val_len = newlength ;
}
2006-07-28 01:04:15 +08:00
safe_php_register_variable ( param , value , new_val_len , array_ptr , 0 TSRMLS_CC ) ;
2012-02-14 16:58:52 +08:00
} else {
if ( count = = PG ( max_input_vars ) + 1 ) {
2014-08-26 02:22:49 +08:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Input variables exceeded " ZEND_LONG_FMT " . To increase the limit change max_input_vars in php.ini. " , PG ( max_input_vars ) ) ;
2012-02-14 16:58:52 +08:00
}
if ( php_rfc1867_callback ! = NULL ) {
multipart_event_formdata event_formdata ;
event_formdata . post_bytes_processed = SG ( read_post_bytes ) ;
event_formdata . name = param ;
event_formdata . value = & value ;
event_formdata . length = value_len ;
event_formdata . newlength = NULL ;
php_rfc1867_callback ( MULTIPART_EVENT_FORMDATA , & event_formdata , & event_extra_data TSRMLS_CC ) ;
}
2003-11-26 17:53:22 +08:00
}
2006-09-10 06:06:27 +08:00
2003-05-24 05:40:45 +08:00
if ( ! strcasecmp ( param , " MAX_FILE_SIZE " ) ) {
2014-07-18 04:10:08 +08:00
# ifdef HAVE_ATOLL
2013-07-23 00:03:11 +08:00
max_file_size = atoll ( value ) ;
2014-07-18 04:10:08 +08:00
# else
max_file_size = strtoll ( value , NULL , 10 ) ;
# endif
2001-10-27 13:26:24 +08:00
}
2001-11-16 11:34:26 +08:00
efree ( param ) ;
2001-12-16 21:34:52 +08:00
efree ( value ) ;
2001-10-27 13:26:24 +08:00
continue ;
2001-09-03 10:31:56 +08:00
}
2002-03-30 10:58:19 +08:00
/* If file_uploads=off, skip the file part */
if ( ! PG ( file_uploads ) ) {
2002-12-14 18:45:25 +08:00
skip_upload = 1 ;
2009-10-28 00:13:48 +08:00
} else if ( upload_cnt < = 0 ) {
skip_upload = 1 ;
sapi_module . sapi_error ( E_WARNING , " Maximum number of allowable file uploads has been exceeded " ) ;
2002-03-30 10:58:19 +08:00
}
2002-04-02 07:02:16 +08:00
/* Return with an error if the posted data is garbled */
2003-01-07 07:51:28 +08:00
if ( ! param & & ! filename ) {
2002-04-02 07:02:16 +08:00
sapi_module . sapi_error ( E_WARNING , " File Upload Mime headers garbled " ) ;
2006-07-23 00:38:29 +08:00
goto fileupload_done ;
2002-04-02 07:02:16 +08:00
}
2009-12-30 02:59:58 +08:00
2003-01-07 07:51:28 +08:00
if ( ! param ) {
is_anonymous = 1 ;
param = emalloc ( MAX_SIZE_ANONNAME ) ;
snprintf ( param , MAX_SIZE_ANONNAME , " %u " , anonindex + + ) ;
} else {
is_anonymous = 0 ;
}
2009-12-30 02:59:58 +08:00
2004-09-12 18:45:14 +08:00
/* New Rule: never repair potential malicious user input */
if ( ! skip_upload ) {
long c = 0 ;
2011-01-19 21:09:05 +08:00
tmp = param ;
2009-12-30 02:59:58 +08:00
2004-09-12 18:45:14 +08:00
while ( * tmp ) {
if ( * tmp = = ' [ ' ) {
c + + ;
} else if ( * tmp = = ' ] ' ) {
c - - ;
2004-09-14 00:00:23 +08:00
if ( tmp [ 1 ] & & tmp [ 1 ] ! = ' [ ' ) {
skip_upload = 1 ;
break ;
}
2004-09-12 18:45:14 +08:00
}
if ( c < 0 ) {
skip_upload = 1 ;
break ;
}
2009-12-30 02:59:58 +08:00
tmp + + ;
2004-09-12 18:45:14 +08:00
}
2012-01-02 07:54:25 +08:00
/* Brackets should always be closed */
if ( c ! = 0 ) {
skip_upload = 1 ;
}
2004-09-12 18:45:14 +08:00
}
2002-04-02 07:02:16 +08:00
2004-11-11 08:38:04 +08:00
total_bytes = cancel_upload = 0 ;
2010-10-04 09:27:33 +08:00
temp_filename = NULL ;
fd = - 1 ;
2009-12-30 02:59:58 +08:00
2006-09-29 18:05:34 +08:00
if ( ! skip_upload & & php_rfc1867_callback ! = NULL ) {
2006-07-23 00:38:29 +08:00
multipart_event_file_start event_file_start ;
event_file_start . post_bytes_processed = SG ( read_post_bytes ) ;
event_file_start . name = param ;
event_file_start . filename = & filename ;
if ( php_rfc1867_callback ( MULTIPART_EVENT_FILE_START , & event_file_start , & event_extra_data TSRMLS_CC ) = = FAILURE ) {
2009-12-30 02:59:58 +08:00
temp_filename = " " ;
2006-09-29 18:05:34 +08:00
efree ( param ) ;
efree ( filename ) ;
continue ;
2006-07-23 00:38:29 +08:00
}
}
2002-12-07 08:48:13 +08:00
if ( skip_upload ) {
2002-12-10 23:36:26 +08:00
efree ( param ) ;
2002-12-10 23:58:31 +08:00
efree ( filename ) ;
2002-12-07 08:48:13 +08:00
continue ;
2006-07-23 00:38:29 +08:00
}
2001-09-03 10:31:56 +08:00
2012-04-03 09:54:57 +08:00
if ( filename [ 0 ] = = ' \0 ' ) {
2004-05-11 23:30:54 +08:00
# if DEBUG_FILE_UPLOAD
2002-04-23 08:14:08 +08:00
sapi_module . sapi_error ( E_NOTICE , " No file uploaded " ) ;
2002-05-31 17:05:39 +08:00
# endif
2001-11-25 02:23:35 +08:00
cancel_upload = UPLOAD_ERROR_D ;
}
2006-07-23 00:38:29 +08:00
offset = 0 ;
2005-07-14 04:44:08 +08:00
end = 0 ;
2012-01-02 07:54:25 +08:00
2010-10-04 09:27:33 +08:00
if ( ! cancel_upload ) {
/* only bother to open temp file if we have data */
blen = multipart_buffer_read ( mbuff , buff , sizeof ( buff ) , & end TSRMLS_CC ) ;
# if DEBUG_FILE_UPLOAD
if ( blen > 0 ) {
# else
/* in non-debug mode we have no problem with 0-length files */
{
# endif
fd = php_open_temporary_fd_ex ( PG ( upload_tmp_dir ) , " php " , & temp_filename , 1 TSRMLS_CC ) ;
upload_cnt - - ;
if ( fd = = - 1 ) {
sapi_module . sapi_error ( E_WARNING , " File upload error - unable to create a temporary file " ) ;
cancel_upload = UPLOAD_ERROR_E ;
}
}
}
while ( ! cancel_upload & & ( blen > 0 ) )
2001-10-27 13:26:24 +08:00
{
2006-07-23 00:38:29 +08:00
if ( php_rfc1867_callback ! = NULL ) {
multipart_event_file_data event_file_data ;
event_file_data . post_bytes_processed = SG ( read_post_bytes ) ;
event_file_data . offset = offset ;
event_file_data . data = buff ;
event_file_data . length = blen ;
event_file_data . newlength = & blen ;
if ( php_rfc1867_callback ( MULTIPART_EVENT_FILE_DATA , & event_file_data , & event_extra_data TSRMLS_CC ) = = FAILURE ) {
cancel_upload = UPLOAD_ERROR_X ;
continue ;
}
}
2009-12-30 02:59:58 +08:00
2014-08-26 01:24:55 +08:00
if ( PG ( upload_max_filesize ) > 0 & & ( zend_long ) ( total_bytes + blen ) > PG ( upload_max_filesize ) ) {
2004-05-11 23:30:54 +08:00
# if DEBUG_FILE_UPLOAD
2014-08-26 02:22:49 +08:00
sapi_module . sapi_error ( E_NOTICE , " upload_max_filesize of " ZEND_LONG_FMT " bytes exceeded - file [%s=%s] not saved " , PG ( upload_max_filesize ) , param , filename ) ;
2004-03-26 05:27:23 +08:00
# endif
2001-11-11 08:45:31 +08:00
cancel_upload = UPLOAD_ERROR_A ;
2014-08-26 01:24:55 +08:00
} else if ( max_file_size & & ( ( zend_long ) ( total_bytes + blen ) > max_file_size ) ) {
2004-05-11 23:30:54 +08:00
# if DEBUG_FILE_UPLOAD
2014-08-26 02:22:49 +08:00
sapi_module . sapi_error ( E_NOTICE , " MAX_FILE_SIZE of " ZEND_LONG_FMT " bytes exceeded - file [%s=%s] not saved " , max_file_size , param , filename ) ;
2004-03-26 05:27:23 +08:00
# endif
2001-11-11 08:45:31 +08:00
cancel_upload = UPLOAD_ERROR_B ;
2001-10-27 13:26:24 +08:00
} else if ( blen > 0 ) {
2014-10-27 23:38:05 +08:00
# ifdef PHP_WIN32
wlen = write ( fd , buff , ( unsigned int ) blen ) ;
# else
2005-04-04 22:59:40 +08:00
wlen = write ( fd , buff , blen ) ;
2014-10-27 23:38:05 +08:00
# endif
2009-12-30 02:59:58 +08:00
2008-03-14 21:11:12 +08:00
if ( wlen = = - 1 ) {
/* write failed */
# if DEBUG_FILE_UPLOAD
sapi_module . sapi_error ( E_NOTICE , " write() failed - %s " , strerror ( errno ) ) ;
# endif
cancel_upload = UPLOAD_ERROR_F ;
} else if ( wlen < blen ) {
2004-05-11 23:30:54 +08:00
# if DEBUG_FILE_UPLOAD
2004-08-11 12:27:01 +08:00
sapi_module . sapi_error ( E_NOTICE , " Only %d bytes were written, expected to write %d " , wlen , blen ) ;
2004-03-26 05:27:23 +08:00
# endif
2005-07-14 04:44:08 +08:00
cancel_upload = UPLOAD_ERROR_F ;
2001-10-27 13:26:24 +08:00
} else {
total_bytes + = wlen ;
}
2006-07-23 00:38:29 +08:00
offset + = wlen ;
2009-12-30 02:59:58 +08:00
}
2010-10-04 09:27:33 +08:00
/* read data for next iteration */
blen = multipart_buffer_read ( mbuff , buff , sizeof ( buff ) , & end TSRMLS_CC ) ;
2004-11-11 08:38:04 +08:00
}
2010-10-04 09:27:33 +08:00
2009-12-30 02:59:58 +08:00
if ( fd ! = - 1 ) { /* may not be initialized if file could not be created */
2005-04-04 22:59:40 +08:00
close ( fd ) ;
2004-11-11 08:38:04 +08:00
}
2010-10-04 09:27:33 +08:00
2005-07-14 04:44:08 +08:00
if ( ! cancel_upload & & ! end ) {
# if DEBUG_FILE_UPLOAD
2012-04-03 09:54:57 +08:00
sapi_module . sapi_error ( E_NOTICE , " Missing mime boundary at the end of the data for file %s " , filename [ 0 ] ! = ' \0 ' ? filename : " " ) ;
2005-07-14 04:44:08 +08:00
# endif
cancel_upload = UPLOAD_ERROR_C ;
}
2004-05-11 23:30:54 +08:00
# if DEBUG_FILE_UPLOAD
2012-04-03 09:54:57 +08:00
if ( filename [ 0 ] ! = ' \0 ' & & total_bytes = = 0 & & ! cancel_upload ) {
2001-11-25 02:23:35 +08:00
sapi_module . sapi_error ( E_WARNING , " Uploaded file size 0 - file [%s=%s] not saved " , param , filename ) ;
2002-07-12 09:49:58 +08:00
cancel_upload = 5 ;
2001-11-25 02:23:35 +08:00
}
2009-12-30 02:59:58 +08:00
# endif
2006-07-23 00:38:29 +08:00
if ( php_rfc1867_callback ! = NULL ) {
multipart_event_file_end event_file_end ;
event_file_end . post_bytes_processed = SG ( read_post_bytes ) ;
event_file_end . temp_filename = temp_filename ;
event_file_end . cancel_upload = cancel_upload ;
if ( php_rfc1867_callback ( MULTIPART_EVENT_FILE_END , & event_file_end , & event_extra_data TSRMLS_CC ) = = FAILURE ) {
cancel_upload = UPLOAD_ERROR_X ;
}
}
2002-05-11 19:58:16 +08:00
if ( cancel_upload ) {
2001-11-25 00:05:22 +08:00
if ( temp_filename ) {
2004-11-11 08:38:04 +08:00
if ( cancel_upload ! = UPLOAD_ERROR_E ) { /* file creation failed */
unlink ( temp_filename ) ;
}
2001-10-27 13:26:24 +08:00
efree ( temp_filename ) ;
}
2009-12-30 02:59:58 +08:00
temp_filename = " " ;
2001-11-16 09:06:48 +08:00
} else {
2014-02-10 14:04:30 +08:00
zend_hash_str_add_ptr ( SG ( rfc1867_uploaded_files ) , temp_filename , strlen ( temp_filename ) , temp_filename ) ;
2001-09-03 10:31:56 +08:00
}
2001-10-27 13:26:24 +08:00
/* is_arr_upload is true when name of file upload field
* ends in [ . * ]
2009-12-30 02:59:58 +08:00
* start_arr is set to point to 1 st [ */
2002-12-30 05:02:17 +08:00
is_arr_upload = ( start_arr = strchr ( param , ' [ ' ) ) & & ( param [ strlen ( param ) - 1 ] = = ' ] ' ) ;
2001-10-27 13:26:24 +08:00
2001-11-25 00:05:22 +08:00
if ( is_arr_upload ) {
2014-10-27 23:38:05 +08:00
array_len = ( int ) strlen ( start_arr ) ;
2001-11-25 00:05:22 +08:00
if ( array_index ) {
efree ( array_index ) ;
}
2009-12-30 03:25:09 +08:00
array_index = estrndup ( start_arr + 1 , array_len - 2 ) ;
2001-10-27 13:26:24 +08:00
}
2009-12-30 02:59:58 +08:00
2001-11-25 00:05:22 +08:00
/* Add $foo_name */
2007-02-24 10:17:47 +08:00
if ( llen < strlen ( param ) + MAX_SIZE_OF_INDEX + 1 ) {
2014-10-27 23:38:05 +08:00
llen = ( int ) strlen ( param ) ;
2007-02-24 10:17:47 +08:00
lbuf = ( char * ) safe_erealloc ( lbuf , llen , 1 , MAX_SIZE_OF_INDEX + 1 ) ;
llen + = MAX_SIZE_OF_INDEX + 1 ;
2001-11-25 00:05:22 +08:00
}
2009-12-30 02:59:58 +08:00
2001-10-27 13:26:24 +08:00
if ( is_arr_upload ) {
if ( abuf ) efree ( abuf ) ;
abuf = estrndup ( param , strlen ( param ) - array_len ) ;
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s_name[%s] " , abuf , array_index ) ;
2001-10-27 13:26:24 +08:00
} else {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s_name " , param ) ;
2001-10-27 13:26:24 +08:00
}
2001-09-03 10:31:56 +08:00
2011-03-06 15:00:30 +08:00
/* The \ check should technically be needed for win32 systems only where
* it is a valid path separator . However , IE in all it ' s wisdom always sends
* the full path of the file on the user ' s filesystem , which means that unless
* the user does basename ( ) they get a bogus file name . Until IE ' s user base drops
* to nill or problem is fixed this code must remain enabled for all systems . */
s = _basename ( internal_encoding , filename TSRMLS_CC ) ;
if ( ! s ) {
s = filename ;
2010-12-02 17:40:53 +08:00
}
2009-12-30 02:59:58 +08:00
2003-01-07 07:51:28 +08:00
if ( ! is_anonymous ) {
2010-12-08 19:27:34 +08:00
safe_php_register_variable ( lbuf , s , strlen ( s ) , NULL , 0 TSRMLS_CC ) ;
2001-10-27 13:26:24 +08:00
}
2001-11-25 00:07:05 +08:00
/* Add $foo[name] */
2001-10-27 13:26:24 +08:00
if ( is_arr_upload ) {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s[name][%s] " , abuf , array_index ) ;
2001-10-27 13:26:24 +08:00
} else {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s[name] " , param ) ;
2001-10-27 13:26:24 +08:00
}
2014-02-10 14:04:30 +08:00
register_http_post_files_variable ( lbuf , s , & PG ( http_globals ) [ TRACK_VARS_FILES ] , 0 TSRMLS_CC ) ;
2001-11-16 11:34:26 +08:00
efree ( filename ) ;
2002-03-10 19:03:04 +08:00
s = NULL ;
2009-12-30 02:59:58 +08:00
2001-11-25 00:07:05 +08:00
/* Possible Content-Type: */
2002-06-05 19:28:33 +08:00
if ( cancel_upload | | ! ( cd = php_mime_get_hdr_value ( header , " Content-Type " ) ) ) {
2001-10-27 13:26:24 +08:00
cd = " " ;
2009-12-30 02:59:58 +08:00
} else {
2002-03-10 19:03:04 +08:00
/* fix for Opera 6.01 */
s = strchr ( cd , ' ; ' ) ;
if ( s ! = NULL ) {
* s = ' \0 ' ;
}
2001-10-27 13:26:24 +08:00
}
2001-11-25 00:07:05 +08:00
/* Add $foo_type */
2001-10-27 13:26:24 +08:00
if ( is_arr_upload ) {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s_type[%s] " , abuf , array_index ) ;
2001-10-27 13:26:24 +08:00
} else {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s_type " , param ) ;
2001-10-27 13:26:24 +08:00
}
2003-01-07 07:51:28 +08:00
if ( ! is_anonymous ) {
2006-07-28 01:04:15 +08:00
safe_php_register_variable ( lbuf , cd , strlen ( cd ) , NULL , 0 TSRMLS_CC ) ;
2003-01-07 07:51:28 +08:00
}
2001-10-27 13:26:24 +08:00
2001-11-25 00:07:05 +08:00
/* Add $foo[type] */
2001-10-27 13:26:24 +08:00
if ( is_arr_upload ) {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s[type][%s] " , abuf , array_index ) ;
2001-10-27 13:26:24 +08:00
} else {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s[type] " , param ) ;
2001-10-27 13:26:24 +08:00
}
2014-02-10 14:04:30 +08:00
register_http_post_files_variable ( lbuf , cd , & PG ( http_globals ) [ TRACK_VARS_FILES ] , 0 TSRMLS_CC ) ;
2001-10-27 13:26:24 +08:00
2002-03-10 19:03:04 +08:00
/* Restore Content-Type Header */
if ( s ! = NULL ) {
* s = ' ; ' ;
}
s = " " ;
2008-10-21 02:42:58 +08:00
{
2011-07-22 19:25:30 +08:00
/* store temp_filename as-is (in case upload_tmp_dir
2008-10-21 02:43:32 +08:00
* contains escapeable characters . escape only the variable name . ) */
zval zfilename ;
2008-10-21 02:42:58 +08:00
2008-10-21 02:43:32 +08:00
/* Initialize variables */
add_protected_variable ( param TSRMLS_CC ) ;
2001-12-16 21:34:52 +08:00
2008-10-21 02:43:32 +08:00
/* if param is of form xxx[.*] this will cut it to xxx */
if ( ! is_anonymous ) {
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & zfilename , temp_filename ) ;
2008-10-21 02:43:32 +08:00
safe_php_register_variable_ex ( param , & zfilename , NULL , 1 TSRMLS_CC ) ;
}
2009-12-30 02:59:58 +08:00
2008-10-21 02:43:32 +08:00
/* Add $foo[tmp_name] */
if ( is_arr_upload ) {
snprintf ( lbuf , llen , " %s[tmp_name][%s] " , abuf , array_index ) ;
} else {
snprintf ( lbuf , llen , " %s[tmp_name] " , param ) ;
}
add_protected_variable ( lbuf TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & zfilename , temp_filename ) ;
register_http_post_files_variable_ex ( lbuf , & zfilename , & PG ( http_globals ) [ TRACK_VARS_FILES ] , 1 TSRMLS_CC ) ;
2008-10-21 02:42:58 +08:00
}
2001-11-11 08:45:31 +08:00
2001-10-27 13:26:24 +08:00
{
2001-11-11 08:45:31 +08:00
zval file_size , error_type ;
2013-08-15 00:59:46 +08:00
int size_overflow = 0 ;
char file_size_buf [ 65 ] ;
2001-11-16 11:34:26 +08:00
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & error_type , cancel_upload ) ;
2001-11-25 00:07:05 +08:00
/* Add $foo[error] */
2001-11-11 09:51:17 +08:00
if ( cancel_upload ) {
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & file_size , 0 ) ;
2001-11-11 09:51:17 +08:00
} else {
2014-08-26 02:22:49 +08:00
if ( total_bytes > ZEND_LONG_MAX ) {
2013-08-15 00:59:46 +08:00
# ifdef PHP_WIN32
if ( _i64toa_s ( total_bytes , file_size_buf , 65 , 10 ) ) {
file_size_buf [ 0 ] = ' 0 ' ;
file_size_buf [ 1 ] = ' \0 ' ;
}
# else
{
int __len = snprintf ( file_size_buf , 65 , " %lld " , total_bytes ) ;
file_size_buf [ __len ] = ' \0 ' ;
}
# endif
size_overflow = 1 ;
} else {
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & file_size , total_bytes ) ;
2013-08-15 00:59:46 +08:00
}
2009-12-30 02:59:58 +08:00
}
2001-11-25 00:05:22 +08:00
if ( is_arr_upload ) {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s[error][%s] " , abuf , array_index ) ;
2001-11-16 11:34:26 +08:00
} else {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s[error] " , param ) ;
2001-11-16 11:34:26 +08:00
}
2014-02-10 14:04:30 +08:00
register_http_post_files_variable_ex ( lbuf , & error_type , & PG ( http_globals ) [ TRACK_VARS_FILES ] , 0 TSRMLS_CC ) ;
2001-11-25 00:07:05 +08:00
/* Add $foo_size */
2001-11-25 00:05:22 +08:00
if ( is_arr_upload ) {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s_size[%s] " , abuf , array_index ) ;
2001-10-27 13:26:24 +08:00
} else {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s_size " , param ) ;
2001-10-27 13:26:24 +08:00
}
2003-01-07 07:51:28 +08:00
if ( ! is_anonymous ) {
2013-08-15 00:59:46 +08:00
if ( size_overflow ) {
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & file_size , file_size_buf ) ;
2013-08-15 00:59:46 +08:00
}
safe_php_register_variable_ex ( lbuf , & file_size , NULL , size_overflow TSRMLS_CC ) ;
2009-12-30 02:59:58 +08:00
}
2001-10-27 13:26:24 +08:00
2001-11-25 00:07:05 +08:00
/* Add $foo[size] */
2001-10-27 13:26:24 +08:00
if ( is_arr_upload ) {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s[size][%s] " , abuf , array_index ) ;
2001-10-27 13:26:24 +08:00
} else {
2007-02-24 10:17:47 +08:00
snprintf ( lbuf , llen , " %s[size] " , param ) ;
2001-10-27 13:26:24 +08:00
}
2013-08-15 00:59:46 +08:00
if ( size_overflow ) {
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & file_size , file_size_buf ) ;
2013-08-15 00:59:46 +08:00
}
2014-02-10 14:04:30 +08:00
register_http_post_files_variable_ex ( lbuf , & file_size , & PG ( http_globals ) [ TRACK_VARS_FILES ] , size_overflow TSRMLS_CC ) ;
2001-10-27 13:26:24 +08:00
}
2001-11-16 11:34:26 +08:00
efree ( param ) ;
2001-10-27 13:26:24 +08:00
}
1999-05-26 06:28:24 +08:00
}
2009-12-30 03:25:09 +08:00
2006-07-23 00:38:29 +08:00
fileupload_done :
if ( php_rfc1867_callback ! = NULL ) {
multipart_event_end event_end ;
2009-12-30 02:59:58 +08:00
2006-07-23 00:38:29 +08:00
event_end . post_bytes_processed = SG ( read_post_bytes ) ;
php_rfc1867_callback ( MULTIPART_EVENT_END , & event_end , & event_extra_data TSRMLS_CC ) ;
}
2009-12-30 02:59:58 +08:00
2010-12-02 17:40:53 +08:00
if ( lbuf ) efree ( lbuf ) ;
if ( abuf ) efree ( abuf ) ;
if ( array_index ) efree ( array_index ) ;
zend_hash_destroy ( & PG ( rfc1867_protected_variables ) ) ;
zend_llist_destroy ( & header ) ;
if ( mbuff - > boundary_next ) efree ( mbuff - > boundary_next ) ;
if ( mbuff - > boundary ) efree ( mbuff - > boundary ) ;
if ( mbuff - > buffer ) efree ( mbuff - > buffer ) ;
if ( mbuff ) efree ( mbuff ) ;
1999-05-26 06:28:24 +08:00
}
2009-12-30 03:25:09 +08:00
/* }}} */
1999-06-13 01:50:39 +08:00
2010-12-08 19:27:34 +08:00
SAPI_API void php_rfc1867_set_multibyte_callbacks (
php_rfc1867_encoding_translation_t encoding_translation ,
2011-03-06 15:00:30 +08:00
php_rfc1867_get_detect_order_t get_detect_order ,
php_rfc1867_set_input_encoding_t set_input_encoding ,
2010-12-08 19:27:34 +08:00
php_rfc1867_getword_t getword ,
2011-03-06 15:00:30 +08:00
php_rfc1867_getword_conf_t getword_conf ,
2010-12-08 19:27:34 +08:00
php_rfc1867_basename_t basename ) /* {{{ */
{
php_rfc1867_encoding_translation = encoding_translation ;
2011-03-06 15:00:30 +08:00
php_rfc1867_get_detect_order = get_detect_order ;
php_rfc1867_set_input_encoding = set_input_encoding ;
2010-12-08 19:27:34 +08:00
php_rfc1867_getword = getword ;
2011-03-06 15:00:30 +08:00
php_rfc1867_getword_conf = getword_conf ;
2010-12-08 19:27:34 +08:00
php_rfc1867_basename = basename ;
2012-01-02 07:54:25 +08:00
}
2010-12-08 19:27:34 +08:00
/* }}} */
1999-06-13 01:50:39 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2001-09-09 21:29:31 +08:00
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
1999-06-13 01:50:39 +08:00
*/