PHP Classes
Icontem

File: rfc1867.php-4.3.11.patch


  Search   All class groups All class groups   Latest entries Latest entries   Top 10 charts Top 10 charts   Newsletter Newsletter   Blog Blog   Forums Forums   Help FAQ Help FAQ  
  Login   Register  
Recommend this page to a friend! ReTweet ReTweet Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Manuel Lemos  >  Forms generation and validation  >  rfc1867.php-4.3.11.patch  
File: rfc1867.php-4.3.11.patch
Role: Auxiliary data
Content type: text/plain
Description: Patch to enable upload progress monitoring in PHP 4.3.11
Class: Forms generation and validation
HTML forms generation and validation.
 

Contents

Class file image Download
diff -x '*.o' -x '*.lo' -c -r php-4.3.11.original/main/rfc1867.c php-4.3.11/main/rfc1867.c
*** php-4.3.11.original/main/rfc1867.c	2005-02-14 22:28:39.000000000 -0200
--- php-4.3.11/main/rfc1867.c	2006-12-18 14:15:29.000000000 -0200
***************
*** 34,39 ****
--- 34,41 ----
  
  #undef DEBUG_FILE_UPLOAD
  
+ PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL;
+ 
  #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
  #include "ext/mbstring/mbstring.h"
  
***************
*** 127,132 ****
--- 129,136 ----
  #define UPLOAD_ERROR_C    3  /* Partially uploaded */
  #define UPLOAD_ERROR_D    4  /* No file uploaded */
  #define UPLOAD_ERROR_E    6  /* Missing /tmp or similar directory */
+ #define UPLOAD_ERROR_F    7  /* Failed to write file to disk */
+ #define UPLOAD_ERROR_X    8  /* File upload stopped by extension */
  
  void php_rfc1867_register_constants(TSRMLS_D)
  {
***************
*** 136,141 ****
--- 140,147 ----
  	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);
  }
  
  static void normalize_protected_variable(char *varname TSRMLS_DC)
***************
*** 700,706 ****
  
  
  /* read until a boundary condition */
! static int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes TSRMLS_DC)
  {
  	int len, max;
  	char *bound;
--- 706,712 ----
  
  
  /* read until a boundary condition */
! static int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes, int *end TSRMLS_DC)
  {
  	int len, max;
  	char *bound;
***************
*** 713,718 ****
--- 719,727 ----
  	/* look for a potential boundary match, only read data up to that point */
  	if ((bound = php_ap_memstr(self->buf_begin, self->bytes_in_buffer, self->boundary_next, self->boundary_next_len, 1))) {
  		max = bound - self->buf_begin;
+ 		if (end && php_ap_memstr(self->buf_begin, self->bytes_in_buffer, self->boundary_next, self->boundary_next_len, 0)) {
+ 			*end = 1;
+ 		}
  	} else {
  		max = self->bytes_in_buffer;
  	}
***************
*** 744,761 ****
    XXX: this is horrible memory-usage-wise, but we only expect
    to do this on small pieces of form data.
  */
! static char *multipart_buffer_read_body(multipart_buffer *self TSRMLS_DC)
  {
  	char buf[FILLUNIT], *out=NULL;
  	int total_bytes=0, read_bytes=0;
  
! 	while((read_bytes = multipart_buffer_read(self, buf, sizeof(buf) TSRMLS_CC))) {
  		out = erealloc(out, total_bytes + read_bytes + 1);
  		memcpy(out + total_bytes, buf, read_bytes);
  		total_bytes += read_bytes;
  	}
  
  	if (out) out[total_bytes] = '\0';
  
  	return out;
  }
--- 753,771 ----
    XXX: this is horrible memory-usage-wise, but we only expect
    to do this on small pieces of form data.
  */
! static char *multipart_buffer_read_body(multipart_buffer *self, unsigned int *len TSRMLS_DC)
  {
  	char buf[FILLUNIT], *out=NULL;
  	int total_bytes=0, read_bytes=0;
  
! 	while((read_bytes = multipart_buffer_read(self, buf, sizeof(buf), NULL TSRMLS_CC))) {
  		out = erealloc(out, total_bytes + read_bytes + 1);
  		memcpy(out + total_bytes, buf, read_bytes);
  		total_bytes += read_bytes;
  	}
  
  	if (out) out[total_bytes] = '\0';
+ 	*len = total_bytes;
  
  	return out;
  }
***************
*** 779,786 ****
  	zend_bool magic_quotes_gpc;
  	multipart_buffer *mbuff;
  	zval *array_ptr = (zval *) arg;
! 	FILE *fp;
  	zend_llist header;
  
  	if (SG(request_info).content_length > SG(post_max_size)) {
  		sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size));
--- 789,797 ----
  	zend_bool magic_quotes_gpc;
  	multipart_buffer *mbuff;
  	zval *array_ptr = (zval *) arg;
! 	int fd=-1;
  	zend_llist header;
+ 	void *event_extra_data = NULL;
  
  	if (SG(request_info).content_length > SG(post_max_size)) {
  		sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size));
***************
*** 839,858 ****
  #endif
  	zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0);
  
  	while (!multipart_buffer_eof(mbuff TSRMLS_CC))
  	{
  		char buff[FILLUNIT];
  		char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
! 		int blen=0, wlen=0;
  
  		zend_llist_clean(&header);
  
  		if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) {
! 			SAFE_RETURN;
  		}
  
  		if ((cd = php_mime_get_hdr_value(header, "Content-Disposition"))) {
  			char *pair=NULL;
  			
  			while (isspace(*cd)) {
  				++cd;
--- 850,880 ----
  #endif
  	zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0);
  
+ 	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;
+ 		}
+ 	}
+ 
  	while (!multipart_buffer_eof(mbuff TSRMLS_CC))
  	{
  		char buff[FILLUNIT];
  		char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
! 		size_t blen=0, wlen=0;
! 		off_t offset;
  
  		zend_llist_clean(&header);
  
  		if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) {
! 			goto fileupload_done;
  		}
  
  		if ((cd = php_mime_get_hdr_value(header, "Content-Disposition"))) {
  			char *pair=NULL;
+ 			int end=0;
  			
  			while (isspace(*cd)) {
  				++cd;
***************
*** 889,901 ****
  
  			/* Normal form variable, safe to read all data into memory */
  			if (!filename && param) {
! 
! 				char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
  
  				if (!value) {
  					value = estrdup("");
  				}
  
  #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
  				if (php_mb_encoding_translation(TSRMLS_C)) {
  					php_mb_gpc_stack_variable(param, value, &val_list, &len_list, 
--- 911,935 ----
  
  			/* Normal form variable, safe to read all data into memory */
  			if (!filename && param) {
! 				unsigned int value_len;
! 				char *value = multipart_buffer_read_body(mbuff, &value_len TSRMLS_CC);
! 				unsigned int new_val_len; /* Dummy variable */
  
  				if (!value) {
  					value = estrdup("");
  				}
  
+ 				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);
+ 				}
+ 
  #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
  				if (php_mb_encoding_translation(TSRMLS_C)) {
  					php_mb_gpc_stack_variable(param, value, &val_list, &len_list, 
***************
*** 917,938 ****
  
  			/* If file_uploads=off, skip the file part */
  			if (!PG(file_uploads)) {
! 				if (filename) {
! 					efree(filename);
! 				}
! 				if (param) {
! 					efree(param);
! 				}
! 				continue;
  			}
  
  			/* Return with an error if the posted data is garbled */
! 			if (!param) {
  				sapi_module.sapi_error(E_WARNING, "File Upload Mime headers garbled");
! 				if (filename) {
! 					efree(filename);
! 				}
! 				SAFE_RETURN;
  			}
  			
  			/* New Rule: never repair potential malicious user input */
--- 951,963 ----
  
  			/* If file_uploads=off, skip the file part */
  			if (!PG(file_uploads)) {
! 				skip_upload = 1;
  			}
  
  			/* Return with an error if the posted data is garbled */
! 			if (!param && !filename) {
  				sapi_module.sapi_error(E_WARNING, "File Upload Mime headers garbled");
! 				goto fileupload_done;
  			}
  			
  			/* New Rule: never repair potential malicious user input */
***************
*** 962,973 ****
  
  			if (!skip_upload) {
  				/* Handle file */
! 				fp = php_open_temporary_file(PG(upload_tmp_dir), "php", &temp_filename TSRMLS_CC);
! 				if (!fp) {
  					sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file");
  					cancel_upload = UPLOAD_ERROR_E;
  				}
  			}
  			if (skip_upload) {
  				efree(param);
  				efree(filename);
--- 987,1021 ----
  
  			if (!skip_upload) {
  				/* Handle file */
! 				fd = php_open_temporary_fd(PG(upload_tmp_dir), "php", &temp_filename TSRMLS_CC);
! 				if (fd==-1) {
  					sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file");
  					cancel_upload = UPLOAD_ERROR_E;
  				}
  			}
+ 			
+ 			if (!skip_upload && php_rfc1867_callback != NULL) {
+ 				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) {
+ 					if (temp_filename) {
+ 						if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
+ 							close(fd);
+ 							unlink(temp_filename);
+ 						}
+ 						efree(temp_filename);
+ 					}
+ 					temp_filename="";
+ 					efree(param);
+ 					efree(filename);
+ 					continue;
+ 				}
+ 			}
+ 
+ 			
  			if (skip_upload) {
  				efree(param);
  				efree(filename);
***************
*** 981,988 ****
  				cancel_upload = UPLOAD_ERROR_D;
  			}
  
! 			while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff) TSRMLS_CC)))
  			{
  				if (PG(upload_max_filesize) > 0 && total_bytes > PG(upload_max_filesize)) {
  					sapi_module.sapi_error(E_WARNING, "upload_max_filesize of %ld bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename);
  					cancel_upload = UPLOAD_ERROR_A;
--- 1029,1053 ----
  				cancel_upload = UPLOAD_ERROR_D;
  			}
  
! 			offset = 0;
! 			end = 0;
! 			while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
  			{
+ 				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;
+ 					}
+ 				}
+ 				
+ 			
  				if (PG(upload_max_filesize) > 0 && total_bytes > PG(upload_max_filesize)) {
  					sapi_module.sapi_error(E_WARNING, "upload_max_filesize of %ld bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename);
  					cancel_upload = UPLOAD_ERROR_A;
***************
*** 990,1007 ****
  					sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
  					cancel_upload = UPLOAD_ERROR_B;
  				} else if (blen > 0) {
! 					wlen = fwrite(buff, 1, blen, fp);
  			
  					if (wlen < blen) {
  						sapi_module.sapi_error(E_WARNING, "Only %d bytes were written, expected to write %d", wlen, blen);
! 						cancel_upload = UPLOAD_ERROR_C;
  					} else {
  						total_bytes += wlen;
  					}
  				} 
  			} 
! 			if (fp) {
! 				fclose(fp);
  			}
  
  #ifdef DEBUG_FILE_UPLOAD
--- 1055,1081 ----
  					sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
  					cancel_upload = UPLOAD_ERROR_B;
  				} else if (blen > 0) {
! 					wlen = write(fd, buff, blen);
  			
  					if (wlen < blen) {
  						sapi_module.sapi_error(E_WARNING, "Only %d bytes were written, expected to write %d", wlen, blen);
! 						cancel_upload = UPLOAD_ERROR_F;
  					} else {
  						total_bytes += wlen;
  					}
+ 					
+ 					offset += wlen;
  				} 
  			} 
! 			if (fd!=-1) {
! 				close(fd);
! 			}
! 
! 			if (!cancel_upload && !end) {
! #ifdef DEBUG_FILE_UPLOAD
! 				sapi_module.sapi_error(E_NOTICE, "Missing mime boundary at the end of the data for file %s", strlen(filename) > 0 ? filename : "");
! #endif
! 				cancel_upload = UPLOAD_ERROR_C;
  			}
  
  #ifdef DEBUG_FILE_UPLOAD
***************
*** 1011,1016 ****
--- 1085,1101 ----
  			}
  #endif		
  
+ 			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;
+ 				}
+ 			}
+ 
  			if (cancel_upload) {
  				if (temp_filename) {
  					if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
***************
*** 1202,1208 ****
  			efree(param);
  		}
  	}
! 
  	SAFE_RETURN;
  }
  
--- 1287,1300 ----
  			efree(param);
  		}
  	}
! fileupload_done:
! 	if (php_rfc1867_callback != NULL) {
! 		multipart_event_end event_end;
! 		
! 		event_end.post_bytes_processed = SG(read_post_bytes);
! 		php_rfc1867_callback(MULTIPART_EVENT_END, &event_end, &event_extra_data TSRMLS_CC);
! 	}
! 	
  	SAFE_RETURN;
  }
  
diff -x '*.o' -x '*.lo' -c -r php-4.3.11.original/main/rfc1867.h php-4.3.11/main/rfc1867.h
*** php-4.3.11.original/main/rfc1867.h	2002-07-11 22:49:58.000000000 -0300
--- php-4.3.11/main/rfc1867.h	2006-12-16 20:44:47.000000000 -0200
***************
*** 1,13 ****
--- 1,76 ----
+ /*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2006 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.01 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_01.txt                                  |
+   | 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.               |
+   +----------------------------------------------------------------------+
+   | Author:                                                              |
+   +----------------------------------------------------------------------+
+ */
+ 
+ /* $Id: rfc1867.h,v 1.13.2.1.2.2 2006/07/26 13:22:06 tony2001 Exp $ */
+ 
  #ifndef RFC1867_H
  #define RFC1867_H
  
  #include "SAPI.h"
  
  #define MULTIPART_CONTENT_TYPE "multipart/form-data"
+ #define MULTIPART_EVENT_START		0
+ #define MULTIPART_EVENT_FORMDATA	1
+ #define MULTIPART_EVENT_FILE_START	2
+ #define MULTIPART_EVENT_FILE_DATA	3
+ #define MULTIPART_EVENT_FILE_END	4
+ #define MULTIPART_EVENT_END		5
+ 
+ typedef struct _multipart_event_start {
+ 	size_t	content_length;
+ } multipart_event_start;
+ 
+ typedef struct _multipart_event_formdata {
+ 	size_t	post_bytes_processed;
+ 	char	*name;
+ 	char	**value;
+ 	size_t	length;
+ 	size_t	*newlength;
+ } multipart_event_formdata;
+ 
+ typedef struct _multipart_event_file_start {
+ 	size_t	post_bytes_processed;
+ 	char	*name;
+ 	char	**filename;
+ } multipart_event_file_start;
+ 
+ typedef struct _multipart_event_file_data {
+ 	size_t	post_bytes_processed;
+ 	off_t	offset;
+ 	char	*data;
+ 	size_t	length;
+ 	size_t	*newlength;	
+ } multipart_event_file_data;
+ 
+ typedef struct _multipart_event_file_end {
+ 	size_t	post_bytes_processed;
+ 	char	*temp_filename;
+ 	int	cancel_upload;
+ } multipart_event_file_end;
+ 
+ typedef struct _multipart_event_end {
+ 	size_t	post_bytes_processed;
+ } multipart_event_end;
  
  SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler);
  
  void destroy_uploaded_files_hash(TSRMLS_D);
  void php_rfc1867_register_constants(TSRMLS_D);
+ extern PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC);
  
  #endif /* RFC1867_H */

 
  Advertise on this site Advertise on this site   Site map Site map   Statistics Statistics   Site tips Site tips   Privacy policy Privacy policy   Contact Contact  

For more information send a message to :
info at phpclasses dot org.
Copyright (c) Icontem 1999-2009 PHP Classes - PHP Class Scripts
  PHP Book Reviews - Reviews of books and other products