Skip to content

Patch: Allow uploading files > 2G https://bugs.php.net/bug.php?id=44522 #372

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 17, 2013
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions main/SAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ typedef struct {
char *post_data, *raw_post_data;
char *cookie_data;
long content_length;
uint post_data_length, raw_post_data_length;
off_t post_data_length, raw_post_data_length;

char *path_translated;
char *request_uri;
Expand Down Expand Up @@ -119,7 +119,7 @@ typedef struct _sapi_globals_struct {
void *server_context;
sapi_request_info request_info;
sapi_headers_struct sapi_headers;
int read_post_bytes;
off_t read_post_bytes;
unsigned char headers_sent;
struct stat global_stat;
char *default_mimetype;
Expand Down
5 changes: 3 additions & 2 deletions main/rfc1867.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
{
char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL;
char *temp_filename = NULL, *lbuf = NULL, *abuf = NULL;
int boundary_len = 0, total_bytes = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0;
int max_file_size = 0, skip_upload = 0, anonindex = 0, is_anonymous;
int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0;
off_t total_bytes = 0, max_file_size = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

max_file_size is later (around line 900) set using

                if (!strcasecmp(param, "MAX_FILE_SIZE")) {
                    max_file_size = atol(value);
                }

this might cause issues on windows where sizeof(long) always equals 4, even on 64 bit systems. In case off_t is a 64 bit integer (or unsized 32 bit) this might lead to unexpected behavior.

Also later, around line 1026 I see

if (PG(upload_max_filesize) > 0 && (long)(total_bytes+blen) > PG(upload_max_filesize)) {
#if DEBUG_FILE_UPLOAD
                    sapi_module.sapi_error(E_NOTICE, "upload_max_filesize of %ld bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename);
#endif
                    cancel_upload = UPLOAD_ERROR_A;
                } else if (max_file_size && ((long)(total_bytes+blen) > max_file_size)) {
#if DEBUG_FILE_UPLOAD
                    sapi_module.sapi_error(E_NOTICE, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
#endif
                    cancel_upload = UPLOAD_ERROR_B;
                } else if (blen > 0) {

those casts to long seem to be wrong after this patch, probably casting to off_t is better %ld should be double checked (while that's debug code only)

Again for Windows: Line 1222 or so reads

                  file_size.value.lval = total_bytes;

lval is a long. long on Windows always is 32bit. Probably we need (unprecise) double or string representation for files with total_bytes > maxint

This is simpler if off_t on Win64 is 32bits, too, which I don't know :-)

int skip_upload = 0, anonindex = 0, is_anonymous;
zval *http_post_files = NULL;
HashTable *uploaded_files = NULL;
multipart_buffer *mbuff;
Expand Down
2 changes: 1 addition & 1 deletion sapi/cgi/cgi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
uint read_bytes = 0;
int tmp_read_bytes;

count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes));
count_bytes = MIN(count_bytes, SG(request_info).content_length - SG(read_post_bytes));
while (read_bytes < count_bytes) {
tmp_read_bytes = read(STDIN_FILENO, buffer + read_bytes, count_bytes - read_bytes);
if (tmp_read_bytes <= 0) {
Expand Down