diff options
| -rw-r--r-- | Changelog | 1 | ||||
| -rw-r--r-- | rfc1867_new.c | 109 |
2 files changed, 75 insertions, 35 deletions
| @@ -3,6 +3,7 @@ | |||
| 3 | - removed dead code | 3 | - removed dead code |
| 4 | - better debian integration | 4 | - better debian integration |
| 5 | - fixed perdir checks | 5 | - fixed perdir checks |
| 6 | - merged PHP changes to RFC1867 code | ||
| 6 | 7 | ||
| 7 | 2015-05-21 - 0.9.38 | 8 | 2015-05-21 - 0.9.38 |
| 8 | - removed code compatibility for PHP <5.4 (lots of code + ifdefs) | 9 | - removed code compatibility for PHP <5.4 (lots of code + ifdefs) |
diff --git a/rfc1867_new.c b/rfc1867_new.c index 318e5a6..e03de44 100644 --- a/rfc1867_new.c +++ b/rfc1867_new.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | +----------------------------------------------------------------------+ | 2 | +----------------------------------------------------------------------+ |
| 3 | | PHP Version 5 | | 3 | | PHP Version 5 | |
| 4 | +----------------------------------------------------------------------+ | 4 | +----------------------------------------------------------------------+ |
| 5 | | Copyright (c) 1997-2013 The PHP Group | | 5 | | Copyright (c) 1997-2016 The PHP Group | |
| 6 | +----------------------------------------------------------------------+ | 6 | +----------------------------------------------------------------------+ |
| 7 | | This source file is subject to version 3.01 of the PHP license, | | 7 | | This source file is subject to version 3.01 of the PHP license, | |
| 8 | | that is bundled with this package in the file LICENSE, and is | | 8 | | that is bundled with this package in the file LICENSE, and is | |
| @@ -34,7 +34,12 @@ | |||
| 34 | #include "php_suhosin.h" | 34 | #include "php_suhosin.h" |
| 35 | #include "suhosin_rfc1867.h" | 35 | #include "suhosin_rfc1867.h" |
| 36 | #include "ext/standard/php_string.h" | 36 | #include "ext/standard/php_string.h" |
| 37 | #include "ext/standard/php_smart_str.h" | ||
| 37 | 38 | ||
| 39 | #if defined(PHP_WIN32) && !defined(HAVE_ATOLL) | ||
| 40 | # define atoll(s) _atoi64(s) | ||
| 41 | # define HAVE_ATOLL 1 | ||
| 42 | #endif | ||
| 38 | 43 | ||
| 39 | #define DEBUG_FILE_UPLOAD ZEND_DEBUG | 44 | #define DEBUG_FILE_UPLOAD ZEND_DEBUG |
| 40 | 45 | ||
| @@ -385,8 +390,12 @@ static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC) | |||
| 385 | static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC) | 390 | static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC) |
| 386 | { | 391 | { |
| 387 | char *line; | 392 | char *line; |
| 388 | mime_header_entry prev_entry = {0}, entry; | 393 | mime_header_entry entry = {0}; |
| 389 | int prev_len, cur_len; | 394 | smart_str buf_value = {0}; |
| 395 | char *key = NULL; | ||
| 396 | |||
| 397 | // mime_header_entry prev_entry = {0}; | ||
| 398 | // int prev_len, cur_len; | ||
| 390 | int newlines = 0; | 399 | int newlines = 0; |
| 391 | 400 | ||
| 392 | /* didn't find boundary, abort */ | 401 | /* didn't find boundary, abort */ |
| @@ -399,11 +408,10 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T | |||
| 399 | while( (line = get_line(self TSRMLS_CC)) && line[0] != '\0' ) | 408 | while( (line = get_line(self TSRMLS_CC)) && line[0] != '\0' ) |
| 400 | { | 409 | { |
| 401 | /* add header to table */ | 410 | /* add header to table */ |
| 402 | char *key = line; | ||
| 403 | char *value = NULL; | 411 | char *value = NULL; |
| 404 | 412 | ||
| 405 | if (php_rfc1867_encoding_translation(TSRMLS_C)) { | 413 | if (php_rfc1867_encoding_translation(TSRMLS_C)) { |
| 406 | self->input_encoding = zend_multibyte_encoding_detector((const unsigned char *)line, strlen(line), self->detect_order, self->detect_order_size TSRMLS_CC); | 414 | self->input_encoding = zend_multibyte_encoding_detector((unsigned char *)line, strlen(line), self->detect_order, self->detect_order_size TSRMLS_CC); |
| 407 | } | 415 | } |
| 408 | 416 | ||
| 409 | /* space in the beginning means same header */ | 417 | /* space in the beginning means same header */ |
| @@ -412,24 +420,26 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T | |||
| 412 | } | 420 | } |
| 413 | 421 | ||
| 414 | if (value) { | 422 | if (value) { |
| 415 | *value = 0; | 423 | if(buf_value.c && key) { |
| 416 | do { value++; } while(isspace(*value)); | 424 | /* new entry, add the old one to the list */ |
| 417 | 425 | smart_str_0(&buf_value); | |
| 418 | entry.value = estrdup(value); | 426 | entry.key = key; |
| 419 | entry.key = estrdup(key); | 427 | entry.value = buf_value.c; |
| 420 | newlines = 0; | 428 | zend_llist_add_element(header, &entry); |
| 429 | buf_value.c = NULL; | ||
| 430 | key = NULL; | ||
| 431 | } | ||
| 421 | 432 | ||
| 422 | } else if (zend_llist_count(header)) { /* If no ':' on the line, add to previous line */ | 433 | *value = '\0'; |
| 434 | do { value++; } while(isspace(*value)); | ||
| 423 | 435 | ||
| 424 | prev_len = strlen(prev_entry.value); | 436 | key = estrdup(line); |
| 425 | cur_len = strlen(line); | 437 | smart_str_appends(&buf_value, value); |
| 426 | 438 | ||
| 427 | entry.value = emalloc(prev_len + cur_len + 1); | 439 | newlines = 0; |
| 428 | memcpy(entry.value, prev_entry.value, prev_len); | ||
| 429 | memcpy(entry.value + prev_len, line, cur_len); | ||
| 430 | entry.value[cur_len + prev_len] = '\0'; | ||
| 431 | 440 | ||
| 432 | entry.key = estrdup(prev_entry.key); | 441 | } else if (buf_value.c) { /* If no ':' on the line, add to previous line */ |
| 442 | smart_str_appends(&buf_value, line); | ||
| 433 | newlines++; | 443 | newlines++; |
| 434 | if (newlines > SUHOSIN_G(upload_max_newlines)) { | 444 | if (newlines > SUHOSIN_G(upload_max_newlines)) { |
| 435 | SUHOSIN_G(abort_request) = 1; | 445 | SUHOSIN_G(abort_request) = 1; |
| @@ -437,13 +447,16 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T | |||
| 437 | return 0; | 447 | return 0; |
| 438 | } | 448 | } |
| 439 | 449 | ||
| 440 | zend_llist_remove_tail(header); | ||
| 441 | } else { | 450 | } else { |
| 442 | continue; | 451 | continue; |
| 443 | } | 452 | } |
| 444 | 453 | } | |
| 454 | if(buf_value.c && key) { | ||
| 455 | /* add the last one to the list */ | ||
| 456 | smart_str_0(&buf_value); | ||
| 457 | entry.key = key; | ||
| 458 | entry.value = buf_value.c; | ||
| 445 | zend_llist_add_element(header, &entry); | 459 | zend_llist_add_element(header, &entry); |
| 446 | prev_entry = entry; | ||
| 447 | } | 460 | } |
| 448 | 461 | ||
| 449 | return 1; | 462 | return 1; |
| @@ -671,8 +684,9 @@ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ | |||
| 671 | { | 684 | { |
| 672 | char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL; | 685 | char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL; |
| 673 | char *temp_filename = NULL, *lbuf = NULL, *abuf = NULL; | 686 | char *temp_filename = NULL, *lbuf = NULL, *abuf = NULL; |
| 674 | int boundary_len = 0, total_bytes = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0; | 687 | int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0; |
| 675 | int max_file_size = 0, skip_upload = 0, anonindex = 0, is_anonymous; | 688 | int64_t total_bytes = 0, max_file_size = 0; |
| 689 | int skip_upload = 0, anonindex = 0, is_anonymous; | ||
| 676 | zval *http_post_files = NULL; | 690 | zval *http_post_files = NULL; |
| 677 | HashTable *uploaded_files = NULL; | 691 | HashTable *uploaded_files = NULL; |
| 678 | multipart_buffer *mbuff; | 692 | multipart_buffer *mbuff; |
| @@ -864,7 +878,7 @@ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ | |||
| 864 | continue; | 878 | continue; |
| 865 | } | 879 | } |
| 866 | 880 | ||
| 867 | if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, new_val_len, &new_val_len TSRMLS_CC)) { | 881 | if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC)) { |
| 868 | if (&suhosin_rfc1867_filter != NULL) { | 882 | if (&suhosin_rfc1867_filter != NULL) { |
| 869 | multipart_event_formdata event_formdata; | 883 | multipart_event_formdata event_formdata; |
| 870 | size_t newlength = new_val_len; | 884 | size_t newlength = new_val_len; |
| @@ -886,7 +900,7 @@ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ | |||
| 886 | if (count == PG(max_input_vars) + 1) { | 900 | if (count == PG(max_input_vars) + 1) { |
| 887 | 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)); | 901 | 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)); |
| 888 | } | 902 | } |
| 889 | 903 | ||
| 890 | if (&suhosin_rfc1867_filter != NULL) { | 904 | if (&suhosin_rfc1867_filter != NULL) { |
| 891 | multipart_event_formdata event_formdata; | 905 | multipart_event_formdata event_formdata; |
| 892 | 906 | ||
| @@ -900,7 +914,11 @@ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ | |||
| 900 | } | 914 | } |
| 901 | 915 | ||
| 902 | if (!strcasecmp(param, "MAX_FILE_SIZE")) { | 916 | if (!strcasecmp(param, "MAX_FILE_SIZE")) { |
| 903 | max_file_size = atol(value); | 917 | #ifdef HAVE_ATOLL |
| 918 | max_file_size = atoll(value); | ||
| 919 | #else | ||
| 920 | max_file_size = strtoll(value, NULL, 10); | ||
| 921 | #endif | ||
| 904 | } | 922 | } |
| 905 | 923 | ||
| 906 | efree(param); | 924 | efree(param); |
| @@ -1212,17 +1230,32 @@ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ | |||
| 1212 | 1230 | ||
| 1213 | { | 1231 | { |
| 1214 | zval file_size, error_type; | 1232 | zval file_size, error_type; |
| 1233 | int size_overflow = 0; | ||
| 1234 | char file_size_buf[65]; | ||
| 1215 | 1235 | ||
| 1216 | error_type.value.lval = cancel_upload; | 1236 | ZVAL_LONG(&error_type, cancel_upload); |
| 1217 | error_type.type = IS_LONG; | ||
| 1218 | 1237 | ||
| 1219 | /* Add $foo[error] */ | 1238 | /* Add $foo[error] */ |
| 1220 | if (cancel_upload) { | 1239 | if (cancel_upload) { |
| 1221 | file_size.value.lval = 0; | 1240 | ZVAL_LONG(&file_size, 0); |
| 1222 | file_size.type = IS_LONG; | ||
| 1223 | } else { | 1241 | } else { |
| 1224 | file_size.value.lval = total_bytes; | 1242 | if (total_bytes > LONG_MAX) { |
| 1225 | file_size.type = IS_LONG; | 1243 | #ifdef PHP_WIN32 |
| 1244 | if (_i64toa_s(total_bytes, file_size_buf, 65, 10)) { | ||
| 1245 | file_size_buf[0] = '0'; | ||
| 1246 | file_size_buf[1] = '\0'; | ||
| 1247 | } | ||
| 1248 | #else | ||
| 1249 | { | ||
| 1250 | int __len = snprintf(file_size_buf, 65, "%lld", total_bytes); | ||
| 1251 | file_size_buf[__len] = '\0'; | ||
| 1252 | } | ||
| 1253 | #endif | ||
| 1254 | size_overflow = 1; | ||
| 1255 | |||
| 1256 | } else { | ||
| 1257 | ZVAL_LONG(&file_size, total_bytes); | ||
| 1258 | } | ||
| 1226 | } | 1259 | } |
| 1227 | 1260 | ||
| 1228 | if (is_arr_upload) { | 1261 | if (is_arr_upload) { |
| @@ -1239,7 +1272,10 @@ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ | |||
| 1239 | snprintf(lbuf, llen, "%s_size", param); | 1272 | snprintf(lbuf, llen, "%s_size", param); |
| 1240 | } | 1273 | } |
| 1241 | if (!is_anonymous) { | 1274 | if (!is_anonymous) { |
| 1242 | safe_php_register_variable_ex(lbuf, &file_size, NULL, 0 TSRMLS_CC); | 1275 | if (size_overflow) { |
| 1276 | ZVAL_STRING(&file_size, file_size_buf, 1); | ||
| 1277 | } | ||
| 1278 | safe_php_register_variable_ex(lbuf, &file_size, NULL, size_overflow TSRMLS_CC); | ||
| 1243 | } | 1279 | } |
| 1244 | 1280 | ||
| 1245 | /* Add $foo[size] */ | 1281 | /* Add $foo[size] */ |
| @@ -1248,7 +1284,10 @@ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ | |||
| 1248 | } else { | 1284 | } else { |
| 1249 | snprintf(lbuf, llen, "%s[size]", param); | 1285 | snprintf(lbuf, llen, "%s[size]", param); |
| 1250 | } | 1286 | } |
| 1251 | register_http_post_files_variable_ex(lbuf, &file_size, http_post_files, 0 TSRMLS_CC); | 1287 | if (size_overflow) { |
| 1288 | ZVAL_STRING(&file_size, file_size_buf, 1); | ||
| 1289 | } | ||
| 1290 | register_http_post_files_variable_ex(lbuf, &file_size, http_post_files, size_overflow TSRMLS_CC); | ||
| 1252 | } | 1291 | } |
| 1253 | efree(param); | 1292 | efree(param); |
| 1254 | } | 1293 | } |
