From dca5128c58f257d921b8ddd7122b83a31f02a91d Mon Sep 17 00:00:00 2001 From: Rui Hirokawa Date: Sat, 25 Oct 2003 10:30:51 +0000 Subject: [PATCH] name/value in multipart/form-date will be converted into internal encoding when mbstring.encoding_translation is On. --- ext/mbstring/mbstring.c | 101 +++++++++++++++++++++++++++------------- ext/mbstring/mbstring.h | 4 +- main/rfc1867.c | 91 +++++++++++++++++++++++++++++++----- 3 files changed, 150 insertions(+), 46 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 7890b78a5e..14f2b19798 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -309,7 +309,7 @@ ZEND_GET_MODULE(mbstring) * of parsed encodings. */ static int -php_mb_parse_encoding_list(const char *value, int value_length, int **return_list, int *return_size, int persistent) +php_mb_parse_encoding_list(const char *value, int value_length, int **return_list, int *return_size, int persistent TSRMLS_DC) { int n, l, size, bauto, *src, *list, *entry, ret = 1; char *p, *p1, *p2, *endp, *tmpstr; @@ -421,7 +421,7 @@ php_mb_parse_encoding_list(const char *value, int value_length, int **return_lis /* {{{ MBSTRING_API php_mb_check_encoding_list */ MBSTRING_API int php_mb_check_encoding_list(const char *encoding_list TSRMLS_DC) { - return php_mb_parse_encoding_list(encoding_list, strlen(encoding_list), NULL, NULL, 0); + return php_mb_parse_encoding_list(encoding_list, strlen(encoding_list), NULL, NULL, 0 TSRMLS_CC); } /* }}} */ @@ -535,7 +535,7 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) { int *list, size; - if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) { + if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) { if (MBSTRG(detect_order_list) != NULL) { free(MBSTRG(detect_order_list)); } @@ -554,7 +554,7 @@ static PHP_INI_MH(OnUpdate_mbstring_http_input) { int *list, size; - if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) { + if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) { if (MBSTRG(http_input_list) != NULL) { free(MBSTRG(http_input_list)); } @@ -632,7 +632,7 @@ static PHP_INI_MH(OnUpdate_mbstring_script_encoding) { int *list, size; - if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) { + if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) { if (MBSTRG(script_encoding_list) != NULL) { free(MBSTRG(script_encoding_list)); } @@ -1272,7 +1272,7 @@ PHP_FUNCTION(mb_detect_order) break; default: convert_to_string_ex(arg1); - if (!php_mb_parse_encoding_list(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1), &list, &size, 0)) { + if (!php_mb_parse_encoding_list(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1), &list, &size, 0 TSRMLS_CC)) { if (list) { efree(list); } @@ -2516,7 +2516,7 @@ MBSTRING_API char * php_mb_convert_encoding(char *input, size_t length, char *_t if (_from_encodings) { list = NULL; size = 0; - php_mb_parse_encoding_list(_from_encodings, strlen(_from_encodings), &list, &size, 0); + php_mb_parse_encoding_list(_from_encodings, strlen(_from_encodings), &list, &size, 0 TSRMLS_CC); if (size == 1) { from_encoding = *list; string.no_encoding = from_encoding; @@ -2747,7 +2747,7 @@ PHP_FUNCTION(mb_detect_encoding) break; default: convert_to_string_ex(arg_list); - if (!php_mb_parse_encoding_list(Z_STRVAL_PP(arg_list), Z_STRLEN_PP(arg_list), &list, &size, 0)) { + if (!php_mb_parse_encoding_list(Z_STRVAL_PP(arg_list), Z_STRLEN_PP(arg_list), &list, &size, 0 TSRMLS_CC)) { if (list) { efree(list); size = 0; @@ -3045,7 +3045,7 @@ PHP_FUNCTION(mb_convert_variables) break; default: convert_to_string_ex(args[1]); - php_mb_parse_encoding_list(Z_STRVAL_PP(args[1]), Z_STRLEN_PP(args[1]), &elist, &elistsz, 0); + php_mb_parse_encoding_list(Z_STRVAL_PP(args[1]), Z_STRLEN_PP(args[1]), &elist, &elistsz, 0 TSRMLS_CC); break; } if (elistsz <= 0) { @@ -3637,9 +3637,10 @@ MBSTRING_API size_t php_mb_gpc_mbchar_bytes(const char *s TSRMLS_DC) /* }}} */ /* {{{ MBSTRING_API int php_mb_gpc_encoding_converter() */ -MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, const char *encoding_to, const char *encoding_from +MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, int num, const char *encoding_to, const char *encoding_from TSRMLS_DC) { + int i; mbfl_string string, result, *ret; enum mbfl_no_encoding from_encoding, to_encoding; mbfl_buffer_converter *convd; @@ -3663,49 +3664,69 @@ MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, const char from_encoding = MBSTRG(http_input_identify); } + if (from_encoding == mbfl_no_encoding_pass) { + return 0; + } + /* initialize string */ mbfl_string_init(&string); mbfl_string_init(&result); string.no_encoding = from_encoding; string.no_language = MBSTRG(current_language); - string.val = (char*)(*str); - string.len = *len; - /* initialize converter */ - convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len TSRMLS_CC); - if (convd == NULL) { - return -1; - } - mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode) TSRMLS_CC); - mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar) TSRMLS_CC); + for (i=0; ival; - *len = ret->len; + /* initialize converter */ + convd = mbfl_buffer_converter_new(from_encoding, to_encoding, string.len TSRMLS_CC); + if (convd == NULL) { + return -1; + } + mbfl_buffer_converter_illegal_mode(convd, MBSTRG(current_filter_illegal_mode) TSRMLS_CC); + mbfl_buffer_converter_illegal_substchar(convd, MBSTRG(current_filter_illegal_substchar) TSRMLS_CC); + + /* do it */ + ret = mbfl_buffer_converter_feed_result(convd, &string, &result TSRMLS_CC); + if (ret != NULL) { + efree(str[i]); + str[i] = ret->val; + len[i] = ret->len; + } + mbfl_buffer_converter_delete(convd TSRMLS_CC); } - mbfl_buffer_converter_delete(convd TSRMLS_CC); - return ret ? 0 : -1; } /* {{{ MBSTRING_API int php_mb_gpc_encoding_detector() */ -MBSTRING_API int php_mb_gpc_encoding_detector(const char *arg_string, int arg_length, char *arg_list TSRMLS_DC) +MBSTRING_API int php_mb_gpc_encoding_detector(char **arg_string, int *arg_length, int num, char *arg_list TSRMLS_DC) { mbfl_string string; enum mbfl_no_encoding *elist; enum mbfl_no_encoding encoding; + mbfl_encoding_detector *identd = NULL; int size, *list; + if (MBSTRG(http_input_list_size) == 1 && + MBSTRG(http_input_list)[0] == mbfl_no_encoding_pass) { + MBSTRG(http_input_identify) = mbfl_no_encoding_pass; + return SUCCESS; + } + + if (MBSTRG(http_input_list_size) == 1 && + MBSTRG(http_input_list)[0] != mbfl_no_encoding_auto && + mbfl_no_encoding2name(MBSTRG(http_input_list)[0]) != NULL) { + MBSTRG(http_input_identify) = MBSTRG(http_input_list)[0]; + return SUCCESS; + } + if (arg_list && strlen(arg_list)>0) { /* make encoding list */ list = NULL; size = 0; - php_mb_parse_encoding_list(arg_list, strlen(arg_list), &list, &size, 0); + php_mb_parse_encoding_list(arg_list, strlen(arg_list), &list, &size, 0 TSRMLS_CC); if (size > 0 && list != NULL) { elist = list; @@ -3728,9 +3749,23 @@ MBSTRING_API int php_mb_gpc_encoding_detector(const char *arg_string, int arg_le mbfl_string_init(&string); string.no_language = MBSTRG(current_language); - string.val = (char*)arg_string; - string.len = arg_length; - encoding = mbfl_identify_encoding_no(&string, elist, size TSRMLS_CC); + + identd = mbfl_encoding_detector_new(elist, size); + + if (identd) { + int n = 0; + while (n < num) { + string.val = (unsigned char*)arg_string[n]; + string.len = arg_length[n]; + if (mbfl_encoding_detector_feed(identd, &string)) { + break; + } + n++; + } + encoding = mbfl_encoding_detector_judge(identd); + mbfl_encoding_detector_delete(identd); + } + if (encoding != mbfl_no_encoding_invalid) { MBSTRG(http_input_identify) = encoding; return SUCCESS; @@ -3812,7 +3847,7 @@ char* php_mb_encoding_detector(const char *arg_string, int arg_length, char *arg /* make encoding list */ list = NULL; size = 0; - php_mb_parse_encoding_list(arg_list, strlen(arg_list), &list, &size, 0); + php_mb_parse_encoding_list(arg_list, strlen(arg_list), &list, &size, 0 TSRMLS_CC); if (size <= 0) { return NULL; } diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index 86739561c0..f9f3f14f15 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -142,9 +142,9 @@ MBSTRING_API int php_mb_encoding_detector_ex(const char *arg_string, int arg_len MBSTRING_API int php_mb_encoding_converter_ex(char **str, int *len, const char *encoding_to, const char *encoding_from TSRMLS_DC); -MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, const char *encoding_to, const char *encoding_from TSRMLS_DC); +MBSTRING_API int php_mb_gpc_encoding_converter(char **str, int *len, int num, const char *encoding_to, const char *encoding_from TSRMLS_DC); -MBSTRING_API int php_mb_gpc_encoding_detector(const char *arg_string, int arg_length, char *arg_list TSRMLS_DC); +MBSTRING_API int php_mb_gpc_encoding_detector(char **arg_string, int *arg_length, int num, char *arg_list TSRMLS_DC); ZEND_BEGIN_MODULE_GLOBALS(mbstring) enum mbfl_no_language language; diff --git a/main/rfc1867.c b/main/rfc1867.c index 0603638353..2a75ad8e70 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -32,13 +32,16 @@ #include "php_variables.h" #include "rfc1867.h" +#undef DEBUG_FILE_UPLOAD + + #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) #include "ext/mbstring/mbstring.h" -#endif -#undef DEBUG_FILE_UPLOAD +static void safe_php_register_variable(char *var, char *strval, zval *track_vars_array, zend_bool override_protection TSRMLS_DC); #define SAFE_RETURN { \ + php_mb_flush_gpc_variables(num_vars, val_list, len_list, array_ptr TSRMLS_CC); \ if (lbuf) efree(lbuf); \ if (abuf) efree(abuf); \ if (array_index) efree(array_index); \ @@ -50,6 +53,59 @@ if (mbuff) efree(mbuff); \ return; } +void php_mb_flush_gpc_variables(int num_vars, char **val_list, int *len_list, zval *array_ptr TSRMLS_DC) +{ + int i; + if (php_mb_encoding_translation(TSRMLS_C)) { + if (num_vars > 0 && + php_mb_gpc_encoding_detector(val_list, len_list, num_vars, NULL TSRMLS_CC) == SUCCESS) { + php_mb_gpc_encoding_converter(val_list, len_list, num_vars, NULL, NULL TSRMLS_CC); + } + for (i=0; i=*num_vars_max){ + (*num_vars_max) += 16; + *pval_list = (char **)erealloc(val_list, *num_vars_max*sizeof(char *)); + *plen_list = (int *)erealloc(len_list, *num_vars_max*sizeof(int)); + val_list=*pval_list; + len_list=*plen_list; + } + val_list[*num_vars] = (char *)estrdup(param); + len_list[*num_vars] = strlen(param); + (*num_vars)++; + val_list[*num_vars] = (char *)estrdup(value); + len_list[*num_vars] = strlen(value); + (*num_vars)++; +} + +#else + +#define SAFE_RETURN { \ + 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); \ + return; } + +#endif /* The longest property name we use in an uploaded file array */ #define MAX_SIZE_OF_INDEX sizeof("[tmp_name]") @@ -546,7 +602,8 @@ static char *php_ap_getword_conf(char **line TSRMLS_DC) #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) if (php_mb_encoding_translation(TSRMLS_C)) { - php_mb_gpc_encoding_detector(str, strlen(str), NULL TSRMLS_CC); + int len=strlen(str); + php_mb_gpc_encoding_detector(&str, &len, 1, NULL TSRMLS_CC); } #endif @@ -700,7 +757,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) FILE *fp; zend_llist header; #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) - int str_len=0; + int str_len = 0, num_vars = 0, num_vars_max = 2*10+1, *len_list = NULL; + char **val_list = NULL; #endif if (SG(request_info).content_length > SG(post_max_size)) { @@ -751,6 +809,12 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) INIT_PZVAL(http_post_files); PG(http_globals)[TRACK_VARS_FILES] = http_post_files; +#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) + if (php_mb_encoding_translation(TSRMLS_C)) { + val_list = (char **)ecalloc(num_vars_max, sizeof(char *)); + len_list = (int *)ecalloc(num_vars_max, sizeof(int)); + } +#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)) @@ -812,13 +876,14 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) if (php_mb_encoding_translation(TSRMLS_C)) { - if (php_mb_gpc_encoding_detector(value, strlen(value), NULL TSRMLS_CC) == SUCCESS) { - str_len = strlen(value); - php_mb_gpc_encoding_converter(&value , &str_len, NULL, NULL TSRMLS_CC); - } + php_mb_gpc_stack_variable(param, value, &val_list, &len_list, + &num_vars, &num_vars_max TSRMLS_CC); + } else { + safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); } -#endif +#else safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC); +#endif if (!strcasecmp(param, "MAX_FILE_SIZE")) { max_file_size = atol(value); } @@ -944,11 +1009,15 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING) if (php_mb_encoding_translation(TSRMLS_C)) { - if(php_mb_gpc_encoding_detector(filename, strlen(filename), NULL TSRMLS_CC) == SUCCESS) { + val_list[num_vars] = filename; + len_list[num_vars] = strlen(filename); + num_vars++; + if(php_mb_gpc_encoding_detector(val_list, len_list, num_vars, NULL TSRMLS_CC) == SUCCESS) { str_len = strlen(filename); - php_mb_gpc_encoding_converter(&filename, &str_len, NULL, NULL TSRMLS_CC); + php_mb_gpc_encoding_converter(&filename, &str_len, 1, NULL, NULL TSRMLS_CC); } s = php_mb_strrchr(filename, '\\' TSRMLS_CC); + num_vars--; } else { s = strrchr(filename, '\\'); } -- 2.40.0