summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.c25
-rw-r--r--Zend/zend_compile.c16
-rw-r--r--Zend/zend_compile.h2
-rw-r--r--Zend/zend_globals.h3
-rw-r--r--ext/filter/filter.c16
-rw-r--r--ext/mbstring/mb_gpc.c2
-rw-r--r--ext/pcre/php_pcre.c2
-rw-r--r--ext/standard/basic_functions.c59
-rw-r--r--ext/standard/basic_functions.h4
-rw-r--r--ext/standard/php_string.h4
-rw-r--r--ext/standard/string.c8
-rw-r--r--main/SAPI.c19
-rw-r--r--main/SAPI.h4
-rw-r--r--main/php_globals.h2
-rw-r--r--main/php_variables.c403
-rw-r--r--main/php_variables.h4
-rw-r--r--main/rfc1867.c1190
-rw-r--r--sapi/apache/mod_php.c6
-rw-r--r--sapi/apache2filter/sapi_apache2.c12
-rw-r--r--sapi/apache2handler/sapi_apache2.c16
-rw-r--r--sapi/cgi/cgi_main.c17
-rw-r--r--unicode-todo.txt3
22 files changed, 492 insertions, 1325 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index f1576b5abf..3445420222 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -195,13 +195,17 @@ ZEND_INI_BEGIN()
STD_ZEND_INI_ENTRY("unicode.fallback_encoding", NULL, ZEND_INI_ALL, OnUpdateEncoding, fallback_encoding_conv, zend_unicode_globals, unicode_globals)
STD_ZEND_INI_ENTRY("unicode.runtime_encoding", NULL, ZEND_INI_ALL, OnUpdateEncoding, runtime_encoding_conv, zend_unicode_globals, unicode_globals)
STD_ZEND_INI_ENTRY("unicode.script_encoding", NULL, ZEND_INI_ALL, OnUpdateEncoding, script_encoding_conv, zend_unicode_globals, unicode_globals)
- STD_ZEND_INI_ENTRY("unicode.http_input_encoding", NULL, ZEND_INI_ALL, OnUpdateEncoding, http_input_encoding_conv, zend_unicode_globals, unicode_globals)
STD_ZEND_INI_ENTRY("unicode.filesystem_encoding", NULL, ZEND_INI_ALL, OnUpdateEncoding, filesystem_encoding_conv, zend_unicode_globals, unicode_globals)
/*
* This is used as a default for the stream contexts. It's not an actual
* UConverter because each stream needs its own.
*/
STD_ZEND_INI_ENTRY("unicode.stream_encoding", "UTF-8", ZEND_INI_ALL, OnUpdateStringUnempty, stream_encoding, zend_unicode_globals, unicode_globals)
+ /*
+ * This is used as a default for the request encoding. It's not an actual
+ * UConverter because the request encoding converter is reset on each request.
+ */
+ STD_ZEND_INI_ENTRY("unicode.request_encoding_default", "UTF-8", ZEND_INI_ALL, OnUpdateStringUnempty, request_encoding_def, zend_unicode_globals, unicode_globals)
ZEND_INI_END()
@@ -1008,8 +1012,8 @@ static void unicode_globals_ctor(zend_unicode_globals *unicode_globals TSRMLS_DC
unicode_globals->runtime_encoding_conv = NULL;
unicode_globals->output_encoding_conv = NULL;
unicode_globals->script_encoding_conv = NULL;
- unicode_globals->http_input_encoding_conv = NULL;
unicode_globals->filesystem_encoding_conv = NULL;
+ unicode_globals->request_encoding_conv = NULL;
zend_set_converter_encoding(&unicode_globals->utf8_conv, "UTF-8");
zend_set_converter_error_mode(unicode_globals->utf8_conv, ZEND_TO_UNICODE, ZEND_CONV_ERROR_STOP);
zend_set_converter_encoding(&unicode_globals->ascii_conv, "US-ASCII");
@@ -1061,11 +1065,6 @@ static void unicode_globals_dtor(zend_unicode_globals *unicode_globals TSRMLS_DC
unicode_globals->script_encoding_conv != unicode_globals->ascii_conv) {
ucnv_close(unicode_globals->script_encoding_conv);
}
- if (unicode_globals->http_input_encoding_conv &&
- unicode_globals->http_input_encoding_conv != unicode_globals->utf8_conv &&
- unicode_globals->http_input_encoding_conv != unicode_globals->ascii_conv) {
- ucnv_close(unicode_globals->http_input_encoding_conv);
- }
if (unicode_globals->utf8_conv) {
ucnv_close(unicode_globals->utf8_conv);
}
@@ -1385,12 +1384,24 @@ static void init_unicode_request_globals(TSRMLS_D) /* {{{ */
UG(default_locale) = safe_estrdup(uloc_getDefault());
UG(default_collator) = NULL;
+ if (strcmp(UG(request_encoding_def), "binary") != 0) {
+ if (zend_set_converter_encoding(&UG(request_encoding_conv), UG(request_encoding_def)) == FAILURE) {
+ zend_error(E_CORE_ERROR, "Unrecognized encoding '%s' used for request_encoding", UG(request_encoding_def));
+ return;
+ }
+ zend_set_converter_error_mode(UG(request_encoding_conv), ZEND_TO_UNICODE, ZEND_CONV_ERROR_STOP);
+ }
+
zend_reset_locale_deps(TSRMLS_C);
}
/* }}} */
static void shutdown_unicode_request_globals(TSRMLS_D) /* {{{ */
{
+ if (UG(request_encoding_conv)) {
+ ucnv_close(UG(request_encoding_conv));
+ UG(request_encoding_conv) = NULL;
+ }
zend_collator_destroy(UG(default_collator));
efree(UG(default_locale));
}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index e55c8b5ebe..86afab0875 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -104,11 +104,25 @@ static void build_runtime_defined_function_key(zval *result, zend_uchar type, co
}
/* }}} */
-int zend_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
+ZEND_API int zend_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
{
auto_global->armed = (auto_global->auto_global_callback ? 1 : 0);
return 0;
}
+
+ZEND_API int zend_auto_global_arm_by_name(const char *name, zend_uint name_len TSRMLS_DC) /* {{{ */
+{
+ zend_auto_global *auto_global;
+
+ if (zend_hash_find(CG(auto_globals), name, name_len+1, (void **) &auto_global)==FAILURE) {
+ return FAILURE;
+ }
+
+ auto_global->armed = 1;
+ CG(auto_globals_cache)[auto_global->index] = NULL;
+
+ return SUCCESS;
+}
/* }}} */
int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC) /* {{{ */
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 52f0f8852c..fb91a42fe9 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -625,6 +625,8 @@ ZEND_API int zend_register_auto_global_ex(const char *name, uint name_len, zend_
ZEND_API zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC);
ZEND_API zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint name_len TSRMLS_DC);
ZEND_API zend_bool zend_u_is_auto_global_ex(zend_uchar type, zstr name, uint name_len, zend_bool runtime, zend_auto_global **ret TSRMLS_DC);
+ZEND_API int zend_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC);
+ZEND_API int zend_auto_global_arm_by_name(const char *name, zend_uint name_len TSRMLS_DC);
ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC);
ZEND_API size_t zend_dirname(char *path, size_t len);
ZEND_API size_t zend_u_dirname(UChar *path, size_t len);
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index b74c8a2dc1..2139e24839 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -292,8 +292,8 @@ struct _zend_unicode_globals {
UConverter *fallback_encoding_conv; /* converter for default encoding for IS_STRING type */
UConverter *runtime_encoding_conv; /* runtime encoding converter */
UConverter *output_encoding_conv; /* output layer converter */
+ UConverter *request_encoding_conv; /* http request encoding converter */
UConverter *script_encoding_conv; /* default script encoding converter */
- UConverter *http_input_encoding_conv;/* http input encoding converter */
UConverter *filesystem_encoding_conv;/* default filesystem converter (entries, not contents) */
UConverter *utf8_conv; /* all-purpose UTF-8 converter */
UConverter *ascii_conv; /* all-purpose ASCII converter */
@@ -301,6 +301,7 @@ struct _zend_unicode_globals {
char *stream_encoding; /* default stream encoding (contents, not FS entries)
Uses name of encoding rather than a real converter
because each stream needs its own instance */
+ char *request_encoding_def; /* the default http request encoding */
uint16_t from_error_mode;
UChar from_subst_char[3];
diff --git a/ext/filter/filter.c b/ext/filter/filter.c
index 853d033e3d..8370a321bc 100644
--- a/ext/filter/filter.c
+++ b/ext/filter/filter.c
@@ -139,7 +139,7 @@ zend_module_entry filter_module_entry = {
filter_functions,
PHP_MINIT(filter),
PHP_MSHUTDOWN(filter),
- NULL,
+ PHP_RINIT(filter),
PHP_RSHUTDOWN(filter),
PHP_MINFO(filter),
"0.11.0",
@@ -287,6 +287,20 @@ PHP_MSHUTDOWN_FUNCTION(filter)
}
/* }}} */
+/* {{{ PHP_RINIT_FUNCTION
+ */
+PHP_RINIT_FUNCTION(filter)
+{
+ IF_G(get_array) = NULL;
+ IF_G(post_array) = NULL;
+ IF_G(cookie_array) = NULL;
+ IF_G(server_array) = NULL;
+ IF_G(env_array) = NULL;
+ IF_G(session_array) = NULL;
+ return SUCCESS;
+}
+/* }}} */
+
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
#define VAR_ARRAY_COPY_DTOR(a) \
diff --git a/ext/mbstring/mb_gpc.c b/ext/mbstring/mb_gpc.c
index 1a7476d4bd..01a4b71557 100644
--- a/ext/mbstring/mb_gpc.c
+++ b/ext/mbstring/mb_gpc.c
@@ -326,7 +326,7 @@ enum mbfl_no_encoding _php_mb_encoding_handler_ex(const php_mb_encoding_handler_
val = estrndup(val, val_len);
if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
/* add variable to symbol table */
- php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
+ php_register_variable_safe(IS_STRING, ZSTR(var), ZSTR(val), new_val_len, array_ptr TSRMLS_CC);
}
efree(val);
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index cc06bd86df..1d4eb94c71 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -996,7 +996,7 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject,
match = subject + offsets[backref<<1];
match_len = offsets[(backref<<1)+1] - offsets[backref<<1];
if (match_len) {
- esc_match = php_addslashes_ex(match, match_len, &esc_match_len, 0, 1 TSRMLS_CC);
+ esc_match = php_addslashes_ex(match, match_len, &esc_match_len, 0 TSRMLS_CC);
} else {
esc_match = match;
esc_match_len = 0;
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 59d9aefb8a..fa4d2a3fc5 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -861,6 +861,13 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_sys_getloadavg, 0)
ZEND_END_ARG_INFO()
#endif
+
+ZEND_BEGIN_ARG_INFO(arginfo_request_set_encoding, 0)
+ ZEND_ARG_INFO(0, encoding)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_request_had_errors, 0)
+ZEND_END_ARG_INFO()
/* }}} */
/* {{{ assert.c */
ZEND_BEGIN_ARG_INFO(arginfo_assert, 0)
@@ -3364,6 +3371,9 @@ const zend_function_entry basic_functions[] = { /* {{{ */
PHP_FE(sys_get_temp_dir, arginfo_sys_get_temp_dir)
+ PHP_FE(request_set_encoding, arginfo_request_set_encoding)
+ PHP_FE(request_had_errors, arginfo_request_had_errors)
+
{NULL, NULL, NULL}
};
/* }}} */
@@ -6213,6 +6223,55 @@ PHP_FUNCTION(sys_getloadavg)
/* }}} */
#endif
+PHP_FUNCTION(request_set_encoding)
+{
+ char *req_enc;
+ int req_enc_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &req_enc, &req_enc_len) == FAILURE) {
+ return;
+ }
+
+ if (req_enc_len == 0 || strcmp(req_enc, "binary") == 0) {
+ /* converter is already unset, no need to re-arm, just return */
+ if (UG(request_encoding_conv) == NULL)
+ return;
+ ucnv_close(UG(request_encoding_conv));
+ UG(request_encoding_conv) = NULL;
+ } else {
+ /* if the converter is the same as the requested one, no need to re-arm, just
+ * return */
+ if (UG(request_encoding_conv)) {
+ UErrorCode status = U_ZERO_ERROR;
+ const char *current = ucnv_getName(UG(request_encoding_conv), &status);
+ if (!ucnv_compareNames(current, req_enc)) {
+ return;
+ }
+ }
+ if (zend_set_converter_encoding(&UG(request_encoding_conv), req_enc) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized encoding '%s'", req_enc);
+ RETURN_FALSE;
+ }
+ zend_set_converter_error_mode(UG(request_encoding_conv), ZEND_TO_UNICODE, ZEND_CONV_ERROR_STOP);
+ }
+
+ zend_auto_global_arm_by_name(ZEND_STRL("_GET") TSRMLS_CC);
+ zend_auto_global_arm_by_name(ZEND_STRL("_POST") TSRMLS_CC);
+ zend_auto_global_arm_by_name(ZEND_STRL("_FILES") TSRMLS_CC);
+ zend_auto_global_arm_by_name(ZEND_STRL("_REQUEST") TSRMLS_CC);
+
+ RETURN_TRUE;
+}
+
+PHP_FUNCTION(request_had_errors)
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ RETURN_BOOL(PG(request_decoding_error));
+}
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h
index b494214f45..0e4dfcf47c 100644
--- a/ext/standard/basic_functions.h
+++ b/ext/standard/basic_functions.h
@@ -141,6 +141,10 @@ PHP_FUNCTION(stream_bucket_new);
PHP_MINIT_FUNCTION(user_filters);
PHP_RSHUTDOWN_FUNCTION(user_filters);
+/* Unicode-related */
+PHP_FUNCTION(request_set_encoding);
+PHP_FUNCTION(request_had_errors);
+
PHPAPI int _php_error_log(int opt_err, char *message, char *opt, char *headers TSRMLS_DC);
PHPAPI char *php_get_current_user(void);
PHPAPI int php_prefix_varname(zval *result, zval *prefix, zstr var_name, int var_name_len, int var_name_type, zend_bool add_underscore TSRMLS_DC);
diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h
index 4a9c8fba9d..c387140355 100644
--- a/ext/standard/php_string.h
+++ b/ext/standard/php_string.h
@@ -129,9 +129,9 @@ PHPAPI UChar *php_u_strtoupper(UChar *s, int *len, const char *locale);
PHPAPI UChar *php_u_strtolower(UChar *s, int *len, const char *locale);
PHPAPI char *php_strtr(char *str, int len, char *str_from, char *str_to, int trlen);
PHPAPI UChar *php_u_addslashes(UChar *str, int length, int *new_length, int freeit TSRMLS_DC);
-PHPAPI UChar *php_u_addslashes_ex(UChar *str, int length, int *new_length, int freeit, int ignore_sybase TSRMLS_DC);
+PHPAPI UChar *php_u_addslashes_ex(UChar *str, int length, int *new_length, int freeit TSRMLS_DC);
PHPAPI char *php_addslashes(char *str, int length, int *new_length, int freeit TSRMLS_DC);
-PHPAPI char *php_addslashes_ex(char *str, int length, int *new_length, int freeit, int ignore_sybase TSRMLS_DC);
+PHPAPI char *php_addslashes_ex(char *str, int length, int *new_length, int freeit TSRMLS_DC);
PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int freeit, char *what, int wlength TSRMLS_DC);
PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC);
PHPAPI void php_u_stripslashes(UChar *str, int *len TSRMLS_DC);
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 47b0e7f84e..447a22c21d 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -4874,13 +4874,13 @@ PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int should_
*/
PHPAPI UChar *php_u_addslashes(UChar *str, int length, int *new_length, int should_free TSRMLS_DC)
{
- return php_u_addslashes_ex(str, length, new_length, should_free, 0 TSRMLS_CC);
+ return php_u_addslashes_ex(str, length, new_length, should_free TSRMLS_CC);
}
/* }}} */
/* {{{ php_u_addslashes_ex
*/
-PHPAPI UChar *php_u_addslashes_ex(UChar *str, int length, int *new_length, int should_free, int ignore_sybase TSRMLS_DC)
+PHPAPI UChar *php_u_addslashes_ex(UChar *str, int length, int *new_length, int should_free TSRMLS_DC)
{
UChar *buf;
int32_t buf_len = 0, i = 0;
@@ -4929,13 +4929,13 @@ PHPAPI UChar *php_u_addslashes_ex(UChar *str, int length, int *new_length, int s
*/
PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_free TSRMLS_DC)
{
- return php_addslashes_ex(str, length, new_length, should_free, 0 TSRMLS_CC);
+ return php_addslashes_ex(str, length, new_length, should_free TSRMLS_CC);
}
/* }}} */
/* {{{ php_addslashes_ex
*/
-PHPAPI char *php_addslashes_ex(char *str, int length, int *new_length, int should_free, int ignore_sybase TSRMLS_DC)
+PHPAPI char *php_addslashes_ex(char *str, int length, int *new_length, int should_free TSRMLS_DC)
{
/* maximum string length, worst case situation */
char *new_str;
diff --git a/main/SAPI.c b/main/SAPI.c
index 55a3defd41..327856c129 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -118,13 +118,22 @@ SAPI_API void sapi_free_header(sapi_header_struct *sapi_header)
SAPI_API void sapi_handle_post(void *arg TSRMLS_DC)
{
if (SG(request_info).post_entry && SG(request_info).content_type_dup) {
+ /*
+ * We need to re-populate post_data from the stored raw POST data in case we had
+ * any before, so that the handler can get to it.
+ */
+ if (SG(request_info).post_data == NULL && SG(request_info).raw_post_data != NULL) {
+ SG(request_info).post_data = estrndup(SG(request_info).raw_post_data, SG(request_info).raw_post_data_length);
+ }
SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg TSRMLS_CC);
if (SG(request_info).post_data) {
efree(SG(request_info).post_data);
SG(request_info).post_data = NULL;
}
+#if 0 /* UTODO see if this works */
efree(SG(request_info).content_type_dup);
SG(request_info).content_type_dup = NULL;
+#endif
}
}
@@ -384,6 +393,8 @@ SAPI_API void sapi_activate(TSRMLS_D)
SG(request_info).headers_only = 0;
}
SG(rfc1867_uploaded_files) = NULL;
+ SG(rfc1867_vars) = NULL;
+ SG(rfc1867_vars) = NULL;
/* handle request mehtod */
if (SG(server_context)) {
@@ -468,6 +479,14 @@ SAPI_API void sapi_deactivate(TSRMLS_D)
if (SG(rfc1867_uploaded_files)) {
destroy_uploaded_files_hash(TSRMLS_C);
}
+ if (SG(rfc1867_vars)) {
+ zend_hash_destroy(SG(rfc1867_vars));
+ FREE_HASHTABLE(SG(rfc1867_vars));
+ }
+ if (SG(rfc1867_files_vars)) {
+ zend_hash_destroy(SG(rfc1867_files_vars));
+ FREE_HASHTABLE(SG(rfc1867_files_vars));
+ }
if (SG(sapi_headers).mimetype) {
efree(SG(sapi_headers).mimetype);
SG(sapi_headers).mimetype = NULL;
diff --git a/main/SAPI.h b/main/SAPI.h
index 064c275b9b..d85a81ed24 100644
--- a/main/SAPI.h
+++ b/main/SAPI.h
@@ -131,6 +131,10 @@ typedef struct _sapi_globals_struct {
zend_bool sapi_started;
time_t global_request_time;
HashTable known_post_content_types;
+
+ /* raw POST and FILES variables from RFC1867 handler */
+ HashTable *rfc1867_vars;
+ HashTable *rfc1867_files_vars;
} sapi_globals_struct;
diff --git a/main/php_globals.h b/main/php_globals.h
index 7b61cca20d..49e6bdfafc 100644
--- a/main/php_globals.h
+++ b/main/php_globals.h
@@ -154,6 +154,8 @@ struct _php_core_globals {
zend_bool mail_x_header;
char *mail_log;
+
+ zend_bool request_decoding_error;
};
diff --git a/main/php_variables.c b/main/php_variables.c
index 027b215173..4f9f98c1ec 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -29,41 +29,82 @@
#include "SAPI.h"
#include "php_logos.h"
#include "zend_globals.h"
+#include "rfc1867.h"
/* for systems that need to override reading of environment variables */
void _php_import_environment_variables(zval *array_ptr TSRMLS_DC);
PHPAPI void (*php_import_environment_variables)(zval *array_ptr TSRMLS_DC) = _php_import_environment_variables;
+static int php_decode_raw_var_array(HashTable *raw_array, zval *track_array TSRMLS_DC);
PHPAPI void php_register_variable(char *var, char *strval, zval *track_vars_array TSRMLS_DC)
{
- php_register_variable_safe(var, strval, strlen(strval), track_vars_array TSRMLS_CC);
+ php_register_variable_safe(IS_STRING, ZSTR(var), ZSTR(strval), strlen(strval), track_vars_array TSRMLS_CC);
}
-/* binary-safe version */
-PHPAPI void php_register_variable_safe(char *var, char *strval, int str_len, zval *track_vars_array TSRMLS_DC)
+PHPAPI int php_register_variable_with_conv(UConverter *conv, char *var, int var_len, char *val, int val_len, zval *array_ptr, int filter_arg TSRMLS_DC)
{
- zval new_entry;
- assert(strval != NULL);
-
- /* Prepare value */
- Z_STRLEN(new_entry) = str_len;
- Z_STRVAL(new_entry) = estrndup(strval, Z_STRLEN(new_entry));
- Z_TYPE(new_entry) = IS_STRING;
+ zstr c_var, c_val;
+ int c_var_len, c_val_len;
+ zend_uchar type = IS_UNICODE;
+
+ if (conv == NULL) {
+ type = IS_STRING;
+ }
+
+ if (type == IS_UNICODE) {
+ c_var.u = c_val.u = NULL;
+ if (zend_string_to_unicode(conv, &c_var.u, &c_var_len, var, var_len TSRMLS_CC) == FAILURE ||
+ zend_string_to_unicode(conv, &c_val.u, &c_val_len, val, val_len TSRMLS_CC) == FAILURE) {
+
+ if (c_var.u) {
+ efree(c_var.u);
+ }
+ if (c_val.u) {
+ efree(c_val.u);
+ }
+ return FAILURE;
+
+ }
+ } else {
+ c_var.s = var;
+ c_var_len = var_len;
+ c_val.s = val;
+ c_val_len = val_len;
+ }
+
+ /* UTODO
+ * do input filtering
+ */
+ php_register_variable_safe(type, c_var, c_val, c_val_len, array_ptr TSRMLS_CC);
- php_register_variable_ex(var, &new_entry, track_vars_array TSRMLS_CC);
+ if (type == IS_UNICODE) {
+ efree(c_var.u);
+ efree(c_val.u);
+ }
+
+ return SUCCESS;
}
-PHPAPI void php_u_register_variable_safe(UChar *var, UChar *strval, int str_len, zval *track_vars_array TSRMLS_DC)
+PHPAPI void php_register_variable_safe(zend_uchar type, zstr var, zstr strval, int str_len, zval *track_vars_array TSRMLS_DC)
{
zval new_entry;
- assert(strval != NULL);
-
- /* Prepare value */
- Z_USTRLEN(new_entry) = str_len;
- Z_USTRVAL(new_entry) = eustrndup(strval, Z_USTRLEN(new_entry));
- Z_TYPE(new_entry) = IS_UNICODE;
+ assert(strval.v != NULL);
- php_u_register_variable_ex(var, &new_entry, track_vars_array TSRMLS_CC);
+ if (type == IS_UNICODE) {
+ /* Prepare value */
+ Z_USTRLEN(new_entry) = str_len;
+ Z_USTRVAL(new_entry) = eustrndup(strval.u, Z_USTRLEN(new_entry));
+ Z_TYPE(new_entry) = IS_UNICODE;
+
+ php_u_register_variable_ex(var.u, &new_entry, track_vars_array TSRMLS_CC);
+ } else {
+ /* Prepare value */
+ Z_STRLEN(new_entry) = str_len;
+ Z_STRVAL(new_entry) = estrndup(strval.s, Z_STRLEN(new_entry));
+ Z_TYPE(new_entry) = IS_STRING;
+
+ php_register_variable_ex(var.s, &new_entry, track_vars_array TSRMLS_CC);
+ }
}
PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array TSRMLS_DC)
@@ -78,7 +119,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
HashTable *symtable1 = NULL;
assert(var_name != NULL);
-
+
if (track_vars_array) {
symtable1 = Z_ARRVAL_P(track_vars_array);
}
@@ -119,6 +160,9 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
return;
}
+#if 0
+ // Do we realy need this, now that register_globals is gone? Is it the job of this
+ // function to guard against calls with active_symbol_table as the array?
/* GLOBALS hijack attempt, reject parameter */
if (symtable1 == EG(active_symbol_table) &&
var_len == sizeof("GLOBALS")-1 &&
@@ -127,6 +171,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
efree(var_orig);
return;
}
+#endif
index = var;
index_len = var_len;
@@ -176,7 +221,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
return;
}
*ip = 0;
- new_idx_len = strlen(index_s);
+ new_idx_len = strlen(index_s);
}
if (!index) {
@@ -184,11 +229,11 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
array_init(gpc_element);
zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
} else {
- if (zend_rt_symtable_find(symtable1, index, index_len + 1, (void **) &gpc_element_p) == FAILURE
+ if (zend_symtable_find(symtable1, index, index_len + 1, (void **) &gpc_element_p) == FAILURE
|| Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {
MAKE_STD_ZVAL(gpc_element);
array_init(gpc_element);
- zend_rt_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
+ zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
}
}
symtable1 = Z_ARRVAL_PP(gpc_element_p);
@@ -212,18 +257,18 @@ plain_var:
if (!index) {
zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
} else {
- /*
+ /*
* According to rfc2965, more specific paths are listed above the less specific ones.
* If we encounter a duplicate cookie name, we should skip it, since it is not possible
* to have the same (plain text) cookie name for the same path and we should not overwrite
* more specific cookies with the less specific ones.
*/
if (PG(http_globals)[TRACK_VARS_COOKIE] &&
- symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) &&
- zend_rt_symtable_exists(symtable1, index, index_len+1)) {
+ symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) &&
+ zend_symtable_exists(symtable1, index, index_len+1)) {
zval_ptr_dtor(&gpc_element);
} else {
- zend_rt_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
+ zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
}
}
}
@@ -234,7 +279,7 @@ PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_a
{
UChar *p = NULL;
UChar *ip; /* index pointer */
- UChar *index;
+ UChar *index, *var_orig;
int var_len, index_len;
zval *gpc_element, **gpc_element_p;
zend_bool is_array;
@@ -255,6 +300,7 @@ PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_a
/*
* Prepare variable name
*/
+ var_orig = eustrdup(var);
ip = u_strchr(var, 0x5b /*'['*/);
if (ip) {
is_array = 1;
@@ -269,6 +315,7 @@ PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_a
var_len = u_strlen(var);
if (var_len==0) { /* empty variable name, or variable name with a space in it */
zval_dtor(val);
+ efree(var_orig);
return;
}
/* ensure that we don't have spaces or dots in the variable name (not binary safe) */
@@ -276,7 +323,7 @@ PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_a
switch(*p) {
case 0x20: /*' '*/
case 0x2e: /*'.'*/
- *p=0x5f; /*'_'*/
+ *p=0x5f; /*'_'*/
break;
}
}
@@ -287,19 +334,16 @@ PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_a
if (is_array) {
int nest_level = 0;
while (1) {
- zstr escaped_index = NULL_ZSTR;
UChar *index_s;
int new_idx_len = 0;
if(++nest_level > PG(max_input_nesting_level)) {
HashTable *ht;
- zstr tmp_var;
/* too many levels of nesting */
ht = Z_ARRVAL_P(track_vars_array);
- tmp_var.u = var;
- zend_u_hash_del(ht, IS_UNICODE, tmp_var, var_len + 1);
+ zend_u_hash_del(ht, IS_UNICODE, ZSTR(var), var_len + 1);
zval_dtor(val);
/* do not output the error message to the screen,
@@ -307,6 +351,7 @@ PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_a
if (!PG(display_errors)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variable nesting level exceeded %ld. To increase the limit change max_input_nesting_level in php.ini.", PG(max_input_nesting_level));
}
+ efree(var_orig);
return;
}
@@ -331,7 +376,7 @@ PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_a
return;
}
*ip = 0;
- new_idx_len = u_strlen(index_s);
+ new_idx_len = u_strlen(index_s);
}
if (!index) {
@@ -339,16 +384,11 @@ PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_a
array_init(gpc_element);
zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
} else {
- escaped_index.u = index;
-
- if (zend_u_symtable_find(symtable1, IS_UNICODE, escaped_index, index_len+1, (void **) &gpc_element_p)==FAILURE
+ if (zend_u_symtable_find(symtable1, IS_UNICODE, ZSTR(index), index_len+1, (void **) &gpc_element_p)==FAILURE
|| Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {
MAKE_STD_ZVAL(gpc_element);
array_init(gpc_element);
- zend_u_symtable_update(symtable1, IS_UNICODE, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
- }
- if (index!=escaped_index.u) {
- efree(escaped_index.u);
+ zend_u_symtable_update(symtable1, IS_UNICODE, ZSTR(index), index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
}
}
symtable1 = Z_ARRVAL_PP(gpc_element_p);
@@ -372,30 +412,34 @@ plain_var:
if (!index) {
zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
} else {
- /* UTODO fix for php_addslashes case */
- /* char *escaped_index = php_addslashes(index, index_len, &index_len, 0 TSRMLS_CC); */
- zstr escaped_index;
-
- escaped_index.u = index;
- zend_u_symtable_update(symtable1, IS_UNICODE, escaped_index, index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
- /* efree(escaped_index); */
+ /*
+ * According to rfc2965, more specific paths are listed above the less specific ones.
+ * If we encounter a duplicate cookie name, we should skip it, since it is not possible
+ * to have the same (plain text) cookie name for the same path and we should not overwrite
+ * more specific cookies with the less specific ones.
+ */
+ if (PG(http_globals)[TRACK_VARS_COOKIE] &&
+ symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) &&
+ zend_u_symtable_exists(symtable1, IS_UNICODE, ZSTR(index), index_len+1)) {
+ zval_ptr_dtor(&gpc_element);
+ } else {
+ zend_u_symtable_update(symtable1, IS_UNICODE, ZSTR(index), index_len+1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
+ }
}
}
+ efree(var_orig);
}
SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
{
char *var, *val, *e, *s, *p;
zval *array_ptr = (zval *) arg;
- UConverter *input_conv = UG(http_input_encoding_conv);
+ UConverter *conv = UG(request_encoding_conv);
if (SG(request_info).post_data == NULL) {
return;
- }
-
- if (!input_conv) {
- input_conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
}
+ PG(request_decoding_error) = 0;
s = SG(request_info).post_data;
e = s + SG(request_info).post_data_length;
@@ -403,11 +447,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
while (s < e && (p = memchr(s, '&', (e - s)))) {
last_value:
if ((val = memchr(s, '=', (p - s)))) { /* have a value */
- UChar *u_var, *u_val;
- int u_var_len, u_val_len;
int var_len;
int val_len;
- UErrorCode status1 = U_ZERO_ERROR, status2 = U_ZERO_ERROR;
var = s;
var_len = val - s;
@@ -415,16 +456,12 @@ last_value:
php_url_decode(var, var_len);
val++;
val_len = php_url_decode(val, (p - val));
- zend_string_to_unicode_ex(input_conv, &u_var, &u_var_len, var, var_len, &status1);
- zend_string_to_unicode_ex(input_conv, &u_val, &u_val_len, val, val_len, &status2);
- if (U_SUCCESS(status1) && U_SUCCESS(status2)) {
- /* UTODO add input filtering */
- php_u_register_variable_safe(u_var, u_val, u_val_len, array_ptr TSRMLS_CC);
- } else {
- /* UTODO set a user-accessible flag to indicate that conversion failed? */
+ if (php_register_variable_with_conv(conv, var, var_len, val, val_len, array_ptr, PARSE_POST) == FAILURE) {
+ zend_error(E_WARNING, "Failed to decode _POST array");
+ PG(request_decoding_error) = 1;
+ zend_hash_clean(Z_ARRVAL_P(array_ptr));
+ return;
}
- efree(u_var);
- efree(u_val);
}
s = p + 1;
}
@@ -448,8 +485,11 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
zval *array_ptr;
int free_buffer = 0;
char *strtok_buf = NULL;
- UConverter *input_conv = UG(http_input_encoding_conv);
-
+ char *arg_names[] = { "_POST", "_GET", "_COOKIE", "string" };
+ UConverter *conv;
+
+ PG(request_decoding_error) = 0;
+
switch (arg) {
case PARSE_POST:
case PARSE_GET:
@@ -484,8 +524,24 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
}
if (arg == PARSE_POST) {
- sapi_handle_post(array_ptr TSRMLS_CC);
- return;
+ if (SG(request_info).post_entry &&
+ SG(request_info).post_entry->post_handler == rfc1867_post_handler) {
+
+ if (SG(rfc1867_vars) == NULL) {
+ sapi_handle_post(NULL TSRMLS_CC);
+ }
+ if (SG(rfc1867_vars) != NULL) {
+ PG(request_decoding_error) = 0;
+ if (php_decode_raw_var_array(SG(rfc1867_vars), array_ptr TSRMLS_CC) == FAILURE) {
+ zend_error(E_WARNING, "Failed to decode _POST array");
+ PG(request_decoding_error) = 1;
+ zend_hash_clean(Z_ARRVAL_P(array_ptr));
+ }
+ }
+ return;
+ } else {
+ sapi_handle_post(array_ptr TSRMLS_CC);
+ }
}
if (arg == PARSE_GET) { /* GET data */
@@ -496,6 +552,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
} else {
free_buffer = 0;
}
+ conv = UG(request_encoding_conv);
} else if (arg == PARSE_COOKIE) { /* Cookie data */
c_var = SG(request_info).cookie_data;
if (c_var && *c_var) {
@@ -507,6 +564,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
} else if (arg == PARSE_STRING) { /* String data */
res = str;
free_buffer = 1;
+ conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
}
if (!res) {
@@ -523,18 +581,10 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
break;
}
- if (!input_conv) {
- input_conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
- }
-
var = php_strtok_r(res, separator, &strtok_buf);
while (var) {
- int var_len;
- /* unsigned int new_val_len; see below */
- UChar *u_var, *u_val;
- int u_var_len, u_val_len;
- UErrorCode status = U_ZERO_ERROR;
+ int var_len, val_len;
val = strchr(var, '=');
@@ -554,37 +604,20 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
var_len = strlen(var);
php_url_decode(var, var_len);
- zend_string_to_unicode_ex(input_conv, &u_var, &u_var_len, var, var_len, &status);
- if (U_FAILURE(status)) {
- /* UTODO set a user-accessible flag to indicate that conversion failed? */
- efree(u_var);
- goto next_var;
- }
-
if (val) { /* have a value */
- int val_len;
-
val_len = php_url_decode(val, strlen(val));
- zend_string_to_unicode_ex(input_conv, &u_val, &u_val_len, val, val_len, &status);
- if (U_FAILURE(status)) {
- /* UTODO set a user-accessible flag to indicate that conversion failed? */
- efree(u_var);
- efree(u_val);
- goto next_var;
- }
} else {
- u_val_len = 0;
- u_val = eustrndup(EMPTY_STR, 0);
+ val = "";
+ val_len = 0;
}
- php_u_register_variable_safe(u_var, u_val, u_val_len, array_ptr TSRMLS_CC);
- /* UTODO need to make input_filter Unicode aware */
- /*
- if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
- php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
+
+ if (php_register_variable_with_conv(conv, var, var_len, val, val_len, array_ptr, arg) == FAILURE) {
+ zend_error(E_WARNING, "Failed to decode %s array", arg_names[arg]);
+ PG(request_decoding_error) = 1;
+ zend_hash_clean(Z_ARRVAL_P(array_ptr));
+ break;
}
- */
- efree(u_var);
- efree(u_val);
+
next_var:
var = php_strtok_r(NULL, separator, &strtok_buf);
}
@@ -624,12 +657,6 @@ void _php_import_environment_variables(zval *array_ptr TSRMLS_DC)
}
}
-zend_bool php_std_auto_global_callback(char *name, uint name_len TSRMLS_DC)
-{
- zend_printf("%s\n", name);
- return 0; /* don't rearm */
-}
-
/* {{{ php_build_argv
*/
static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC)
@@ -637,11 +664,11 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC)
zval *arr, *argc, *tmp;
int count = 0;
char *ss, *space;
-
+
if (!(SG(request_info).argc || track_vars_array)) {
return;
}
-
+
ALLOC_INIT_ZVAL(arr);
array_init(arr);
@@ -668,6 +695,10 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC)
}
/* auto-type */
ALLOC_ZVAL(tmp);
+ /* UTODO
+ * use UG(request_encoding) here. This also means that we need to clean out
+ * and re-arm $_SERVER and clean out $argv on request_set_encoding()
+ */
ZVAL_RT_STRING(tmp, ss, 1);
INIT_PZVAL(tmp);
count++;
@@ -697,7 +728,7 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC)
Z_ADDREF_P(argc);
zend_ascii_hash_update(&EG(symbol_table), "argv", sizeof("argv"), &arr, sizeof(zval *), NULL);
zend_ascii_hash_add(&EG(symbol_table), "argc", sizeof("argc"), &argc, sizeof(zval *), NULL);
- }
+ }
if (track_vars_array) {
Z_ADDREF_P(arr);
Z_ADDREF_P(argc);
@@ -798,9 +829,72 @@ static void php_autoglobal_merge(HashTable *dest, HashTable *src TSRMLS_DC)
}
/* }}} */
+static int php_decode_raw_var_array(HashTable *raw_array, zval *track_array TSRMLS_DC)
+{
+ zstr raw_var;
+ uint raw_var_len;
+ zval **raw_value;
+ zstr var, value;
+ int var_len, value_len;
+ ulong num_index;
+ zend_uchar type = IS_UNICODE;
+ UConverter *conv = UG(request_encoding_conv);
+
+ if (conv == NULL) {
+ type = IS_STRING;
+ }
+
+ for (zend_hash_internal_pointer_reset(raw_array);
+ zend_hash_get_current_data(raw_array, (void **)&raw_value) == SUCCESS;
+ zend_hash_move_forward(raw_array)) {
+
+ zend_hash_get_current_key_ex(raw_array, &raw_var, &raw_var_len, &num_index, 0, NULL);
+
+ if (type == IS_UNICODE) {
+ var.u = value.u = NULL;
+
+ if (zend_string_to_unicode(conv, &var.u, &var_len, raw_var.s, raw_var_len) == FAILURE) {
+ return FAILURE;
+ }
+
+ if (Z_TYPE_PP(raw_value) == IS_STRING) {
+ if (zend_string_to_unicode(conv, &value.u, &value_len, Z_STRVAL_PP(raw_value), Z_STRLEN_PP(raw_value)) == FAILURE) {
+ efree(var.u);
+ return FAILURE;
+ }
+
+ /* UTODO add input filtering */
+ php_register_variable_safe(IS_UNICODE, var, value, value_len, track_array TSRMLS_CC);
+ efree(value.u);
+ } else {
+ php_u_register_variable_ex(var.u, *raw_value, track_array TSRMLS_CC);
+ }
+
+ efree(var.u);
+ } else {
+ var.s = raw_var.s;
+ var_len = raw_var_len;
+ if (Z_TYPE_PP(raw_value) == IS_STRING) {
+ value.s = Z_STRVAL_PP(raw_value);
+ value_len = Z_STRLEN_PP(raw_value);
+
+ /* UTODO add input filtering */
+ php_register_variable_safe(IS_STRING, var, value, value_len, track_array TSRMLS_CC);
+ } else {
+ php_register_variable_ex(var.s, *raw_value, track_array TSRMLS_CC);
+ }
+ }
+ }
+
+ return SUCCESS;
+}
+
static zend_bool php_auto_globals_create_server(char *name, uint name_len TSRMLS_DC);
static zend_bool php_auto_globals_create_env(char *name, uint name_len TSRMLS_DC);
static zend_bool php_auto_globals_create_request(char *name, uint name_len TSRMLS_DC);
+static zend_bool php_auto_globals_decode_get(char *name, uint name_len TSRMLS_DC);
+static zend_bool php_auto_globals_decode_post(char *name, uint name_len TSRMLS_DC);
+static zend_bool php_auto_globals_decode_files(char *name, uint name_len TSRMLS_DC);
/* {{{ php_hash_environment
*/
@@ -831,13 +925,6 @@ int php_hash_environment(TSRMLS_D)
for (p=PG(variables_order); p && *p; p++) {
switch(*p) {
- case 'p':
- case 'P':
- if (!_gpc_flags[0] && !SG(headers_sent) && SG(request_info).request_method && !strcasecmp(SG(request_info).request_method, "POST")) {
- sapi_module.treat_data(PARSE_POST, NULL, NULL TSRMLS_CC); /* POST Data */
- _gpc_flags[0] = 1;
- }
- break;
case 'c':
case 'C':
if (!_gpc_flags[1]) {
@@ -845,13 +932,7 @@ int php_hash_environment(TSRMLS_D)
_gpc_flags[1] = 1;
}
break;
- case 'g':
- case 'G':
- if (!_gpc_flags[2]) {
- sapi_module.treat_data(PARSE_GET, NULL, NULL TSRMLS_CC); /* GET Data */
- _gpc_flags[2] = 1;
- }
- break;
+
case 'e':
case 'E':
if (!jit_initialization && !_gpc_flags[3]) {
@@ -860,6 +941,7 @@ int php_hash_environment(TSRMLS_D)
_gpc_flags[3] = 1;
}
break;
+
case 's':
case 'S':
if (!jit_initialization && !_gpc_flags[4]) {
@@ -890,16 +972,57 @@ int php_hash_environment(TSRMLS_D)
zend_ascii_hash_update(&EG(symbol_table), auto_global_records[i].name, auto_global_records[i].name_len, &PG(http_globals)[i], sizeof(zval *), NULL);
}
- /* Create _REQUEST */
- if (!jit_initialization) {
- zend_auto_global_disable_jit("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC);
- php_auto_globals_create_request("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC);
- }
-
return SUCCESS;
}
/* }}} */
+static zend_bool php_auto_globals_decode_get(char *name, uint name_len TSRMLS_DC)
+{
+ sapi_module.treat_data(PARSE_GET, NULL, NULL TSRMLS_CC); /* GET Data */
+ zend_ascii_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_GET], sizeof(zval *), NULL);
+ Z_ADDREF_P(PG(http_globals)[TRACK_VARS_GET]);
+ return 0;
+}
+
+static zend_bool php_auto_globals_decode_post(char *name, uint name_len TSRMLS_DC)
+{
+ if (SG(request_info).request_method && !strcasecmp(SG(request_info).request_method, "POST")) {
+ sapi_module.treat_data(PARSE_POST, NULL, NULL TSRMLS_CC); /* POST Data */
+ zend_ascii_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_POST], sizeof(zval *), NULL);
+ Z_ADDREF_P(PG(http_globals)[TRACK_VARS_POST]);
+ }
+ return 0;
+}
+
+static zend_bool php_auto_globals_decode_files(char *name, uint name_len TSRMLS_DC)
+{
+ if (PG(http_globals)[TRACK_VARS_FILES]) {
+ zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_FILES]);
+ }
+ ALLOC_ZVAL(PG(http_globals)[TRACK_VARS_FILES]);
+ array_init(PG(http_globals)[TRACK_VARS_FILES]);
+ INIT_PZVAL(PG(http_globals)[TRACK_VARS_FILES]);
+ zend_ascii_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_FILES], sizeof(zval *), NULL);
+ Z_ADDREF_P(PG(http_globals)[TRACK_VARS_FILES]);
+
+ if (SG(request_info).post_entry &&
+ SG(request_info).post_entry->post_handler == rfc1867_post_handler) {
+
+ if (SG(rfc1867_files_vars) == NULL) {
+ sapi_handle_post(NULL TSRMLS_DC);
+ }
+ if (SG(rfc1867_files_vars) != NULL) {
+ PG(request_decoding_error) = 0;
+ if (php_decode_raw_var_array(SG(rfc1867_files_vars), PG(http_globals)[TRACK_VARS_FILES] TSRMLS_CC) == FAILURE) {
+ zend_error(E_WARNING, "Failed to decode _FILES array");
+ PG(request_decoding_error) = 1;
+ zend_hash_clean(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_FILES]));
+ }
+ }
+ }
+ return 0;
+}
+
static zend_bool php_auto_globals_create_server(char *name, uint name_len TSRMLS_DC)
{
if (PG(variables_order) && (strchr(PG(variables_order),'S') || strchr(PG(variables_order),'s'))) {
@@ -918,7 +1041,7 @@ static zend_bool php_auto_globals_create_server(char *name, uint name_len TSRMLS
}
} else {
php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC);
- }
+ }
}
} else {
@@ -948,7 +1071,7 @@ static zend_bool php_auto_globals_create_env(char *name, uint name_len TSRMLS_DC
zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_ENV]);
}
PG(http_globals)[TRACK_VARS_ENV] = env_vars;
-
+
if (PG(variables_order) && (strchr(PG(variables_order),'E') || strchr(PG(variables_order),'e'))) {
php_import_environment_variables(PG(http_globals)[TRACK_VARS_ENV] TSRMLS_CC);
}
@@ -980,6 +1103,7 @@ static zend_bool php_auto_globals_create_request(char *name, uint name_len TSRML
case 'g':
case 'G':
if (!_gpc_flags[0]) {
+ zend_u_is_auto_global_ex(IS_STRING, ZSTR("_GET"), sizeof("_GET")-1, 1, NULL TSRMLS_CC);
php_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]) TSRMLS_CC);
_gpc_flags[0] = 1;
}
@@ -987,6 +1111,7 @@ static zend_bool php_auto_globals_create_request(char *name, uint name_len TSRML
case 'p':
case 'P':
if (!_gpc_flags[1]) {
+ zend_u_is_auto_global_ex(IS_STRING, ZSTR("_POST"), sizeof("_POST")-1, 1, NULL TSRMLS_CC);
php_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]) TSRMLS_CC);
_gpc_flags[1] = 1;
}
@@ -1007,13 +1132,13 @@ static zend_bool php_auto_globals_create_request(char *name, uint name_len TSRML
void php_startup_auto_globals(TSRMLS_D)
{
- zend_register_auto_global("_GET", sizeof("_GET")-1, NULL TSRMLS_CC);
- zend_register_auto_global("_POST", sizeof("_POST")-1, NULL TSRMLS_CC);
+ zend_register_auto_global_ex("_GET", sizeof("_GET")-1, php_auto_globals_decode_get, 1 TSRMLS_CC);
+ zend_register_auto_global_ex("_POST", sizeof("_POST")-1, php_auto_globals_decode_post, 1 TSRMLS_CC);
zend_register_auto_global("_COOKIE", sizeof("_COOKIE")-1, NULL TSRMLS_CC);
zend_register_auto_global("_SERVER", sizeof("_SERVER")-1, php_auto_globals_create_server TSRMLS_CC);
zend_register_auto_global("_ENV", sizeof("_ENV")-1, php_auto_globals_create_env TSRMLS_CC);
- zend_register_auto_global("_REQUEST", sizeof("_REQUEST")-1, php_auto_globals_create_request TSRMLS_CC);
- zend_register_auto_global("_FILES", sizeof("_FILES")-1, NULL TSRMLS_CC);
+ zend_register_auto_global_ex("_REQUEST", sizeof("_REQUEST")-1, php_auto_globals_create_request, 1 TSRMLS_CC);
+ zend_register_auto_global_ex("_FILES", sizeof("_FILES")-1, php_auto_globals_decode_files, 1 TSRMLS_CC);
}
/*
diff --git a/main/php_variables.h b/main/php_variables.h
index eea0cb041e..938d5b9697 100644
--- a/main/php_variables.h
+++ b/main/php_variables.h
@@ -39,10 +39,10 @@ void php_startup_auto_globals(TSRMLS_D);
extern PHPAPI void (*php_import_environment_variables)(zval *array_ptr TSRMLS_DC);
PHPAPI void php_register_variable(char *var, char *val, zval *track_vars_array TSRMLS_DC);
/* binary-safe version */
-PHPAPI void php_register_variable_safe(char *var, char *val, int val_len, zval *track_vars_array TSRMLS_DC);
+PHPAPI void php_register_variable_safe(zend_uchar type, zstr var, zstr strval, int str_len, zval *track_vars_array TSRMLS_DC);
PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_array TSRMLS_DC);
-PHPAPI void php_u_register_variable_safe(UChar *var, UChar *strval, int str_len, zval *track_vars_array TSRMLS_DC);
PHPAPI void php_u_register_variable_ex(UChar *var, zval *val, zval *track_vars_array TSRMLS_DC);
+PHPAPI int php_register_variable_with_conv(UConverter *conv, char *var, int var_len, char *val, int val_len, zval *array_ptr, int input_type TSRMLS_DC);
int php_hash_environment(TSRMLS_D);
END_EXTERN_C()
diff --git a/main/rfc1867.c b/main/rfc1867.c
index 80a92d632a..18219cbdfd 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -41,7 +41,6 @@ PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **
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); \
@@ -49,63 +48,6 @@ PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **
if (mbuff) efree(mbuff); \
return; }
-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
-#include "ext/mbstring/mbstring.h"
-
-static void safe_php_register_variable(char *var, char *strval, int val_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC);
-
-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; i+=2){
- safe_php_register_variable(val_list[i], val_list[i+1], len_list[i+1], array_ptr, 0 TSRMLS_CC);
- efree(val_list[i]);
- efree(val_list[i+1]);
- }
- efree(val_list);
- efree(len_list);
- }
-}
-
-void php_mb_gpc_realloc_buffer(char ***pval_list, int **plen_list, int *num_vars_max, int inc TSRMLS_DC)
-{
- /* allow only even increments */
- if (inc & 1) {
- inc++;
- }
- (*num_vars_max) += inc;
- *pval_list = (char **)erealloc(*pval_list, (*num_vars_max+2)*sizeof(char *));
- *plen_list = (int *)erealloc(*plen_list, (*num_vars_max+2)*sizeof(int));
-}
-
-void php_mb_gpc_stack_variable(char *param, char *value, char ***pval_list, int **plen_list, int *num_vars, int *num_vars_max TSRMLS_DC)
-{
- char **val_list=*pval_list;
- int *len_list=*plen_list;
-
- if (*num_vars>=*num_vars_max){
- php_mb_gpc_realloc_buffer(pval_list, plen_list, num_vars_max,
- 16 TSRMLS_CC);
- /* in case realloc relocated the buffer */
- 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)++;
-}
-
-#endif
-
/* The longest property name we use in an uploaded file array */
#define MAX_SIZE_OF_INDEX sizeof("[tmp_name]")
@@ -134,214 +76,6 @@ void php_rfc1867_register_constants(TSRMLS_D)
REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_EXTENSION", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
}
-static void normalize_protected_variable(char *varname TSRMLS_DC)
-{
- char *s=varname, *index=NULL, *indexend=NULL, *p;
-
- /* overjump leading space */
- while (*s == ' ') {
- s++;
- }
-
- /* and remove it */
- if (s != varname) {
- memmove(varname, s, strlen(s)+1);
- }
-
- for (p=varname; *p && *p != '['; p++) {
- switch(*p) {
- case ' ':
- case '.':
- *p='_';
- break;
- }
- }
-
- /* find index */
- index = strchr(varname, '[');
- if (index) {
- index++;
- s=index;
- } else {
- return;
- }
-
- /* done? */
- while (index) {
-
- while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
- index++;
- }
- indexend = strchr(index, ']');
- indexend = indexend ? indexend + 1 : index + strlen(index);
-
- if (s != index) {
- memmove(s, index, strlen(index)+1);
- s += indexend-index;
- } else {
- s = indexend;
- }
-
- if (*s == '[') {
- s++;
- index = s;
- } else {
- index = NULL;
- }
- }
-
- *s = '\0';
-}
-
-
-static void normalize_u_protected_variable(UChar *varname TSRMLS_DC)
-{
- UChar *s=varname, *index=NULL, *indexend=NULL, *p;
-
- /* overjump leading space */
- while (*s == 0x20 /*' '*/) {
- s++;
- }
-
- /* and remove it */
- if (s != varname) {
- u_memmove(varname, s, u_strlen(s)+1);
- }
-
- for (p=varname; *p && *p != 0x5b /*'['*/; p++) {
- switch(*p) {
- case 0x20: /*' '*/
- case 0x2e: /*'.'*/
- *p=0x5f; /*'_'*/
- break;
- }
- }
-
- /* find index */
- index = u_strchr(varname, 0x5b /*'['*/);
- if (index) {
- index++;
- s=index;
- } else {
- return;
- }
-
- /* done? */
- while (index) {
-
- while (*index == 0x20 /*' '*/ ||
- *index == 0x0d /*'\r'*/ ||
- *index == 0x0a /*'\n'*/ ||
- *index == 0x09 /*'\t'*/) {
- index++;
- }
- indexend = u_strchr(index, 0x5d /*']'*/);
- indexend = indexend ? indexend + 1 : index + u_strlen(index);
-
- if (s != index) {
- u_memmove(s, index, u_strlen(index)+1);
- s += indexend-index;
- } else {
- s = indexend;
- }
-
- if (*s == 0x5b /*'['*/) {
- s++;
- index = s;
- } else {
- index = NULL;
- }
- }
- *s++ = 0;
-}
-
-static void add_protected_variable(char *varname TSRMLS_DC)
-{
- int dummy=1;
-
- normalize_protected_variable(varname TSRMLS_CC);
- zend_hash_add(&PG(rfc1867_protected_variables), varname, strlen(varname)+1, &dummy, sizeof(int), NULL);
-}
-
-
-static void add_u_protected_variable(UChar *varname TSRMLS_DC)
-{
- int dummy=1;
-
- normalize_u_protected_variable(varname TSRMLS_CC);
- zend_u_hash_add(&PG(rfc1867_protected_variables), IS_UNICODE, ZSTR(varname), u_strlen(varname)+1, &dummy, sizeof(int), NULL);
-}
-
-
-static zend_bool is_protected_variable(char *varname TSRMLS_DC)
-{
- normalize_protected_variable(varname TSRMLS_CC);
- return zend_hash_exists(&PG(rfc1867_protected_variables), varname, strlen(varname)+1);
-}
-
-
-static zend_bool is_u_protected_variable(UChar *varname TSRMLS_DC)
-{
- normalize_u_protected_variable(varname TSRMLS_CC);
- return zend_u_hash_exists(&PG(rfc1867_protected_variables), IS_UNICODE, ZSTR(varname), u_strlen(varname)+1);
-}
-
-
-static void safe_php_register_variable(char *var, char *strval, int val_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC)
-{
- if (override_protection || !is_protected_variable(var TSRMLS_CC)) {
- php_register_variable_safe(var, strval, val_len, track_vars_array TSRMLS_CC);
- }
-}
-
-
-static void safe_php_register_variable_ex(char *var, zval *val, zval *track_vars_array, zend_bool override_protection TSRMLS_DC)
-{
- if (override_protection || !is_protected_variable(var TSRMLS_CC)) {
- php_register_variable_ex(var, val, track_vars_array TSRMLS_CC);
- }
-}
-
-
-static void safe_u_php_register_variable(UChar *var, UChar *str_val, int str_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC)
-{
- if (override_protection || !is_u_protected_variable(var TSRMLS_CC)) {
- php_u_register_variable_safe(var, str_val, str_len, track_vars_array TSRMLS_CC);
- }
-}
-
-
-static void safe_u_php_register_variable_ex(UChar *var, zval *val, zval *track_vars_array, zend_bool override_protection TSRMLS_DC)
-{
- if (override_protection || !is_u_protected_variable(var TSRMLS_CC)) {
- php_u_register_variable_ex(var, val, track_vars_array TSRMLS_CC);
- }
-}
-
-
-static void register_http_post_files_variable(char *strvar, char *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC)
-{
- safe_php_register_variable(strvar, val, strlen(val), http_post_files, override_protection TSRMLS_CC);
-}
-
-
-static void register_u_http_post_files_variable(UChar *strvar, UChar *val, int val_len, zval *http_post_files, zend_bool override_protection TSRMLS_DC)
-{
- safe_u_php_register_variable(strvar, val, val_len, http_post_files, override_protection TSRMLS_CC);
-}
-
-
-static void register_http_post_files_variable_ex(char *var, zval *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC)
-{
- safe_php_register_variable_ex(var, val, http_post_files, override_protection TSRMLS_CC);
-}
-
-
-static void register_u_http_post_files_variable_ex(UChar *var, zval *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC)
-{
- safe_u_php_register_variable_ex(var, val, http_post_files, override_protection TSRMLS_CC);
-}
-
static int unlink_filename(char **filename TSRMLS_DC)
{
@@ -357,33 +91,6 @@ void destroy_uploaded_files_hash(TSRMLS_D)
FREE_HASHTABLE(SG(rfc1867_uploaded_files));
}
-
-static inline UChar *php_ap_to_unicode(char *in, int32_t in_len, int32_t *out_len TSRMLS_DC)
-{
- UErrorCode status = U_ZERO_ERROR;
- UChar *buf;
- int buf_len = 0;
- UConverter *input_conv = UG(http_input_encoding_conv);
-
- if (!input_conv) {
- input_conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
- }
-
- input_conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
- zend_string_to_unicode_ex(input_conv, &buf, &buf_len, in, in_len, &status);
- if (U_SUCCESS(status)) {
- if (out_len)
- *out_len = buf_len;
- return buf;
- } else {
- efree(buf);
- if (out_len)
- *out_len = 0;
- return NULL;
- }
-}
-
-
/*
* Following code is based on apache_multipart_buffer.c from libapreq-0.33 package.
*
@@ -662,44 +369,6 @@ static char *php_mime_get_hdr_value(zend_llist header, char *key)
}
-static UChar *php_u_ap_getword(UChar **line, UChar stop TSRMLS_DC)
-{
- UChar *pos = *line, quote;
- UChar *res;
-
- while (*pos && *pos != stop) {
-
- if ((quote = *pos) == '"' || quote == '\'') {
- ++pos;
- while (*pos && *pos != quote) {
- if (*pos == '\\' && pos[1] && pos[1] == quote) {
- pos += 2;
- } else {
- ++pos;
- }
- }
- if (*pos) {
- ++pos;
- }
- } else ++pos;
-
- }
- if (*pos == '\0') {
- res = eustrdup(*line);
- *line += u_strlen(*line);
- return res;
- }
-
- res = eustrndup(*line, pos - *line);
-
- while (*pos == stop) {
- ++pos;
- }
-
- *line = pos;
- return res;
-}
-
static char *php_ap_getword(char **line, char stop)
{
@@ -740,24 +409,6 @@ static char *php_ap_getword(char **line, char stop)
}
-static UChar *substring_u_conf(UChar *start, int len, UChar quote TSRMLS_DC)
-{
- UChar *result = eumalloc(len + 2);
- UChar *resp = result;
- int i;
-
- for (i = 0; i < len; ++i) {
- if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
- *resp++ = start[++i];
- } else {
- *resp++ = start[i];
- }
- }
-
- *resp++ = 0;
- return result;
-}
-
static char *substring_conf(char *start, int len, char quote TSRMLS_DC)
{
@@ -769,19 +420,7 @@ static char *substring_conf(char *start, int len, char quote TSRMLS_DC)
if (start[i] == '\\' && (start[i + 1] == '\\' || (quote && start[i + 1] == quote))) {
*resp++ = start[++i];
} else {
-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
- if (php_mb_encoding_translation(TSRMLS_C)) {
- size_t j = php_mb_gpc_mbchar_bytes(start+i TSRMLS_CC);
- while (j-- > 0 && i < len) {
- *resp++ = start[i++];
- }
- --i;
- } else {
- *resp++ = start[i];
- }
-#else
*resp++ = start[i];
-#endif
}
}
@@ -790,72 +429,10 @@ static char *substring_conf(char *start, int len, char quote TSRMLS_DC)
}
-static UChar *php_u_ap_getword_conf(UChar **line TSRMLS_DC)
-{
- UChar *str = *line, *strend, *res, quote;
-
- while (*str && u_isspace(*str)) {
- ++str;
- }
-
- if (!*str) {
- *line = str;
- return USTR_MAKE("");
- }
-
- if ((quote = *str) == '"' || quote == '\'') {
- strend = str + 1;
-look_for_quote:
- while (*strend && *strend != quote) {
- if (*strend == '\\' && strend[1] && strend[1] == quote) {
- strend += 2;
- } else {
- ++strend;
- }
- }
- if (*strend && *strend == quote) {
- UChar p = *(strend + 1);
- if (p != '\r' && p != '\n' && p != '\0') {
- strend++;
- goto look_for_quote;
- }
- }
-
- res = substring_u_conf(str + 1, strend - str - 1, quote TSRMLS_CC);
-
- if (*strend == quote) {
- ++strend;
- }
-
- } else {
-
- strend = str;
- while (*strend && !u_isspace(*strend)) {
- ++strend;
- }
- res = substring_u_conf(str, strend - str, 0 TSRMLS_CC);
- }
-
- while (*strend && u_isspace(*strend)) {
- ++strend;
- }
-
- *line = strend;
- return res;
-}
-
-
static char *php_ap_getword_conf(char **line TSRMLS_DC)
{
char *str = *line, *strend, *res, quote;
-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
- if (php_mb_encoding_translation(TSRMLS_C)) {
- int len=strlen(str);
- php_mb_gpc_encoding_detector(&str, &len, 1, NULL TSRMLS_CC);
- }
-#endif
-
while (*str && isspace(*str)) {
++str;
}
@@ -1001,603 +578,39 @@ static char *multipart_buffer_read_body(multipart_buffer *self, unsigned int *le
return out;
}
-static SAPI_POST_HANDLER_FUNC(rfc1867_post_handler_unicode)
+static void register_raw_var_ex(char *var, zval *value, HashTable *array TSRMLS_DC)
{
- char *boundary, *boundary_end = NULL;
- UChar *temp_filename=NULL, *array_index = NULL, *lbuf = NULL, *abuf = NULL;
- UChar *start_arr = NULL, *s = NULL;
- char *ascii_temp_filename = 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;
- zval *http_post_files=NULL; HashTable *uploaded_files=NULL;
- multipart_buffer *mbuff;
- zval *array_ptr = (zval *) arg;
- FILE *fp;
- zend_llist header;
- void *event_extra_data = NULL;
- UConverter *input_conv = UG(http_input_encoding_conv);
- U_STRING_DECL(name_key, "name", 4);
- U_STRING_DECL(filename_key, "filename", 8);
- U_STRING_DECL(maxfilesize_key, "MAX_FILE_SIZE", 13);
- static zend_bool did_string_init = FALSE;
- int llen = 0;
-
- 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));
- return;
- }
-
- /* Get the boundary */
- boundary = strstr(content_type_dup, "boundary");
- if (!boundary || !(boundary=strchr(boundary, '='))) {
- sapi_module.sapi_error(E_WARNING, "Missing boundary in multipart/form-data POST data");
- return;
- }
-
- boundary++;
- boundary_len = strlen(boundary);
-
- if (boundary[0] == '"') {
- boundary++;
- boundary_end = strchr(boundary, '"');
- if (!boundary_end) {
- sapi_module.sapi_error(E_WARNING, "Invalid boundary in multipart/form-data POST data");
- return;
- }
- } else {
- /* search for the end of the boundary */
- boundary_end = strchr(boundary, ',');
- }
- if (boundary_end) {
- boundary_end[0] = '\0';
- boundary_len = boundary_end-boundary;
- }
-
- /* Initialize the buffer */
- if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) {
- sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer");
- return;
- }
-
- /* Initialize $_FILES[] */
- zend_u_hash_init(&PG(rfc1867_protected_variables), 5, NULL, NULL, 0, 1);
-
- ALLOC_HASHTABLE(uploaded_files);
- zend_u_hash_init(uploaded_files, 5, NULL, (dtor_func_t) free_estring, 0, 1);
- SG(rfc1867_uploaded_files) = uploaded_files;
-
- ALLOC_ZVAL(http_post_files);
- array_init(http_post_files);
- INIT_PZVAL(http_post_files);
- PG(http_globals)[TRACK_VARS_FILES] = http_post_files;
-
- zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0);
-
- if (!did_string_init) {
- U_STRING_INIT(name_key, "name", 4);
- U_STRING_INIT(filename_key, "filename", 8);
- U_STRING_INIT(maxfilesize_key, "MAX_FILE_SIZE", 13);
- did_string_init = TRUE;
- }
-
- if (!input_conv) {
- input_conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
- }
-
- 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;
- size_t blen=0, wlen=0;
- off_t offset;
- UChar *param = NULL, *filename = NULL, *tmp = NULL;
- int32_t param_len;
-
- 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"))) {
- UChar *pair = NULL;
- UChar *ucd = NULL, *ucd_start = NULL;
- int32_t ucd_len;
- int end=0;
-
- while (isspace(*cd)) {
- ++cd;
- }
-
- ucd_start = php_ap_to_unicode(cd, strlen(cd), &ucd_len TSRMLS_CC);
- if (!ucd) {
- /* UTODO error condition */
- }
- ucd = ucd_start;
-
- while (*ucd && (pair = php_u_ap_getword(&ucd, 0x3b /*';'*/ TSRMLS_CC)))
- {
- UChar *key=NULL, *word = pair;
-
- while (u_isspace(*ucd)) {
- ++ucd;
- }
-
- if (u_strchr(pair, '=')) {
- key = php_u_ap_getword(&pair, 0x3d /*'='*/ TSRMLS_CC);
-
- if (!u_strcasecmp(key, name_key, 0)) {
- if (param) {
- efree(param);
- }
- param = php_u_ap_getword_conf(&pair TSRMLS_CC);
- } else if (!u_strcasecmp(key, filename_key, 0)) {
- if (filename) {
- efree(filename);
- }
- filename = php_u_ap_getword_conf(&pair TSRMLS_CC);
- }
- }
- if (key) {
- efree(key);
- }
- efree(word);
- }
-
- efree(ucd_start);
-
- /* Normal form variable, safe to read all data into memory */
- if (!filename && param) {
- UChar *u_val;
- int32_t u_val_len;
- unsigned int value_len;
- UErrorCode status = U_ZERO_ERROR;
-
- char *value = multipart_buffer_read_body(mbuff, &value_len TSRMLS_CC);
- /* unsigned int new_val_len; Dummy variable */
-
- if (value) {
- /* UTODO use 'charset' parameter for conversion */
- zend_string_to_unicode_ex(input_conv, &u_val, &u_val_len, value, value_len, &status);
- if (U_FAILURE(status)) {
- /* UTODO set a user-accessible flag to indicate that conversion failed? */
- goto var_done;
- }
- } else {
- u_val_len = 0;
- u_val = USTR_MAKE("");
- }
-
- /* UTODO use input filtering */
- /* if (sapi_module.input_filter(PARSE_POST, param, &u_val, u_val_len, &new_val_len TSRMLS_CC)) { */
- if (php_rfc1867_callback != NULL) {
- multipart_event_formdata event_formdata;
- size_t newlength = (size_t) u_val_len;
-
- event_formdata.post_bytes_processed = SG(read_post_bytes);
- event_formdata.name = ZSTR(param);
- event_formdata.value = PZSTR(u_val);
- event_formdata.length = (size_t) u_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);
- efree(u_val);
- continue;
- }
- u_val_len = (int32_t) newlength;
- }
-
- safe_u_php_register_variable(param, u_val, u_val_len, array_ptr, 0 TSRMLS_CC);
- /* } else if (php_rfc1867_callback != NULL) {
- multipart_event_formdata event_formdata;
-
- event_formdata.post_bytes_processed = SG(read_post_bytes);
- event_formdata.name = ZSTR(param);
- event_formdata.value = PZSTR(u_val);
- event_formdata.length = u_val_len;
- event_formdata.newlength = NULL;
- php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC);
- } */
-
- if (!u_strcasecmp(param, maxfilesize_key, 0)) {
- max_file_size = zend_u_strtol(u_val, NULL, 10);
- }
-
-var_done:
- efree(param);
- efree(value);
- efree(u_val);
- continue;
- }
-
- /* 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;
- }
-
- if (!param) {
- is_anonymous = 1;
- param = eumalloc(MAX_SIZE_ANONNAME);
- u_snprintf(param, MAX_SIZE_ANONNAME, "%u", anonindex++);
- } else {
- is_anonymous = 0;
- }
- param_len = u_strlen(param);
-
- /* New Rule: never repair potential malicious user input */
- if (!skip_upload) {
- UChar32 c = 0;
- int32_t ic, l_ic;
- long l = 0;
-
- for (ic = 0; ic < param_len; ) {
- l_ic = ic;
- U16_NEXT(param, ic, param_len, c);
- if (c == 0x5b /*'['*/) {
- l++;
- } else if (c == 0x5d /*']'*/) {
- l--;
- l_ic = ic;
- U16_NEXT(param, ic, param_len, c);
- if (ic < param_len && c != 0x5b /*'['*/) {
- skip_upload = 1;
- break;
- } else {
- /* go back so that the same character is retrieved again */
- ic = l_ic;
- }
- }
- if (l < 0) {
- skip_upload = 1;
- break;
- }
- }
- }
-
- total_bytes = cancel_upload = 0;
-
- if (!skip_upload) {
- /* Handle file */
- fp = php_open_temporary_file(PG(upload_tmp_dir), "php", &ascii_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;
- }
- temp_filename = zend_ascii_to_unicode(ascii_temp_filename, strlen(ascii_temp_filename)+1 ZEND_FILE_LINE_CC);
- }
-
- 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 = ZSTR(param);
- event_file_start.filename = PZSTR(filename);
- if (php_rfc1867_callback(MULTIPART_EVENT_FILE_START, &event_file_start, &event_extra_data TSRMLS_CC) == FAILURE) {
- if (ascii_temp_filename) {
- if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
- fclose(fp);
- unlink(ascii_temp_filename);
- }
- efree(ascii_temp_filename);
- }
- if (temp_filename) {
- efree(temp_filename);
- }
- temp_filename = EMPTY_STR;
- efree(param);
- efree(filename);
- continue;
- }
- }
-
-
- if (skip_upload) {
- efree(param);
- efree(filename);
- continue;
- }
-
- if(u_strlen(filename) == 0) {
-#if DEBUG_FILE_UPLOAD
- sapi_module.sapi_error(E_NOTICE, "No file uploaded");
-#endif
- 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+blen) > PG(upload_max_filesize)) {
-#if DEBUG_FILE_UPLOAD
- sapi_module.sapi_error(E_NOTICE, "upload_max_filesize of %ld bytes exceeded - file [%r=%r] not saved", PG(upload_max_filesize), param, filename);
-#endif
- cancel_upload = UPLOAD_ERROR_A;
- } else if (max_file_size && ((total_bytes+blen) > max_file_size)) {
-#if DEBUG_FILE_UPLOAD
- sapi_module.sapi_error(E_NOTICE, "MAX_FILE_SIZE of %ld bytes exceeded - file [%r=%r] not saved", max_file_size, param, filename);
-#endif
- cancel_upload = UPLOAD_ERROR_B;
- } else if (blen > 0) {
- wlen = fwrite(buff, 1, blen, fp);
-
- 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) {
-#if DEBUG_FILE_UPLOAD
- sapi_module.sapi_error(E_NOTICE, "Only %d bytes were written, expected to write %d", wlen, blen);
-#endif
- cancel_upload = UPLOAD_ERROR_C;
- } else {
- total_bytes += wlen;
- }
-
- offset += wlen;
- }
- }
- if (fp) { /* may not be initialized if file could not be created */
- fclose(fp);
- }
- if (!cancel_upload && !end) {
-#if DEBUG_FILE_UPLOAD
- sapi_module.sapi_error(E_NOTICE, "Missing mime boundary at the end of the data for file %v", u_strlen(filename) > 0 ? filename : EMPTY_STR);
-#endif
- cancel_upload = UPLOAD_ERROR_C;
- }
-#if DEBUG_FILE_UPLOAD
- if(u_strlen(filename) > 0 && total_bytes == 0 && !cancel_upload) {
- sapi_module.sapi_error(E_WARNING, "Uploaded file size 0 - file [%r=%r] not saved", param, filename);
- cancel_upload = 5;
- }
-#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 = ZSTR(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 */
- unlink(ascii_temp_filename);
- }
- efree(ascii_temp_filename);
- efree(temp_filename);
- }
- temp_filename = EMPTY_STR;
- } else {
- zend_u_hash_add(SG(rfc1867_uploaded_files), IS_UNICODE, ZSTR(temp_filename), u_strlen(temp_filename) + 1, &ascii_temp_filename, sizeof(char *), NULL);
- }
-
- /* is_arr_upload is true when name of file upload field
- * ends in [.*]
- * start_arr is set to point to 1st [
- */
- is_arr_upload = (start_arr = u_strchr(param, 0x5b /*'['*/)) && (param[u_strlen(param)-1] == 0x5d /*']'*/);
-
- if (is_arr_upload) {
- array_len = u_strlen(start_arr);
- if (array_index) {
- efree(array_index);
- }
- array_index = eustrndup(start_arr+1, array_len-2);
- }
-
- /* Add $foo_name */
- if (lbuf) {
- efree(lbuf);
- }
- llen = u_strlen(param) + MAX_SIZE_OF_INDEX + 1;
- lbuf = eumalloc(llen);
-
- if (is_arr_upload) {
- if (abuf) efree(abuf);
- abuf = eustrndup(param, u_strlen(param)-array_len);
- u_snprintf(lbuf, llen, "%S_name[%S]", abuf, array_index);
- } else {
- u_snprintf(lbuf, llen, "%S_name", param);
- }
-
- /* The \ check should technically be needed for win32 systems only where
- * it is a valid path separator. However, IE in all its 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 = u_strrchr(filename, '\\');
- if ((tmp = u_strrchr(filename, 0x2f /*'/'*/)) > s) {
- s = tmp;
- }
-
- if (!is_anonymous) {
- if (s && s > filename) {
- safe_u_php_register_variable(lbuf, s+1, u_strlen(s+1), NULL, 0 TSRMLS_CC);
- } else {
- safe_u_php_register_variable(lbuf, filename, u_strlen(filename), NULL, 0 TSRMLS_CC);
- }
- }
-
- /* Add $foo[name] */
- if (is_arr_upload) {
- u_snprintf(lbuf, llen, "%S[name][%S]", abuf, array_index);
- } else {
- u_snprintf(lbuf, llen, "%S[name]", param);
- }
- if (s && s > filename) {
- register_u_http_post_files_variable(lbuf, s+1, u_strlen(s+1), http_post_files, 0 TSRMLS_CC);
- } else {
- register_u_http_post_files_variable(lbuf, filename, u_strlen(filename), http_post_files, 0 TSRMLS_CC);
- }
- efree(filename);
- s = NULL;
-
- /* Possible Content-Type: */
- if (cancel_upload || !(cd = php_mime_get_hdr_value(header, "Content-Type"))) {
- ucd = ecalloc(1, UBYTES(1));
- ucd_len = 0;
- } else {
- ucd = php_ap_to_unicode(cd, strlen(cd), &ucd_len TSRMLS_CC);
- if (!ucd) {
- /* UTODO error condition */
- }
- /* fix for Opera 6.01 */
- s = u_strchr(ucd, 0x3b /*';'*/);
- if (s != NULL) {
- *s = 0;
- ucd_len = u_strlen(ucd);
- }
- }
-
- /* Add $foo_type */
- if (is_arr_upload) {
- u_snprintf(lbuf, llen, "%S_type[%S]", abuf, array_index);
- } else {
- u_snprintf(lbuf, llen, "%S_type", param);
- }
- if (!is_anonymous) {
- safe_u_php_register_variable(lbuf, ucd, ucd_len, NULL, 0 TSRMLS_CC);
- }
-
- /* Add $foo[type] */
- if (is_arr_upload) {
- u_snprintf(lbuf, llen, "%S[type][%S]", abuf, array_index);
- } else {
- u_snprintf(lbuf, llen, "%S[type]", param);
- }
- register_u_http_post_files_variable(lbuf, ucd, ucd_len, http_post_files, 0 TSRMLS_CC);
-
- efree(ucd);
- s = EMPTY_STR;
-
- /* Initialize variables */
- add_u_protected_variable(param TSRMLS_CC);
-
- /* if param is of form xxx[.*] this will cut it to xxx */
- if (!is_anonymous) {
- safe_u_php_register_variable(param, temp_filename, u_strlen(temp_filename), NULL, 1 TSRMLS_CC);
- }
-
- /* Add $foo[tmp_name] */
- if (is_arr_upload) {
- u_snprintf(lbuf, llen, "%S[tmp_name][%S]", abuf, array_index);
- } else {
- u_snprintf(lbuf, llen, "%S[tmp_name]", param);
- }
- add_u_protected_variable(lbuf TSRMLS_CC);
- register_u_http_post_files_variable(lbuf, temp_filename, u_strlen(temp_filename), http_post_files, 1 TSRMLS_CC);
- if (!cancel_upload) {
- efree(temp_filename);
- }
-
- {
- zval file_size, error_type;
-
- error_type.value.lval = cancel_upload;
- error_type.type = IS_LONG;
-
- /* Add $foo[error] */
- if (cancel_upload) {
- file_size.value.lval = 0;
- file_size.type = IS_LONG;
- } else {
- file_size.value.lval = total_bytes;
- file_size.type = IS_LONG;
- }
-
- if (is_arr_upload) {
- u_snprintf(lbuf, llen, "%S[error][%S]", abuf, array_index);
- } else {
- u_snprintf(lbuf, llen, "%S[error]", param);
- }
- register_u_http_post_files_variable_ex(lbuf, &error_type, http_post_files, 0 TSRMLS_CC);
-
- /* Add $foo_size */
- if (is_arr_upload) {
- u_snprintf(lbuf, llen, "%S_size[%S]", abuf, array_index);
- } else {
- u_snprintf(lbuf, llen, "%S_size", param);
- }
- if (!is_anonymous) {
- safe_u_php_register_variable_ex(lbuf, &file_size, NULL, 0 TSRMLS_CC);
- }
+ zend_hash_update(array, var, strlen(var)+1, &value, sizeof(zval *), NULL TSRMLS_CC);
+}
- /* Add $foo[size] */
- if (is_arr_upload) {
- u_snprintf(lbuf, llen, "%S[size][%S]", abuf, array_index);
- } else {
- u_snprintf(lbuf, llen, "%S[size]", param);
- }
- register_u_http_post_files_variable_ex(lbuf, &file_size, http_post_files, 0 TSRMLS_CC);
- }
- efree(param);
- }
- }
+static void register_raw_var(char *var, char *str, int str_len, HashTable *array TSRMLS_DC)
+{
+ zval *new_entry;
+ assert(str != NULL);
-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);
- }
+ /* Prepare value */
+ MAKE_STD_ZVAL(new_entry);
+ Z_STRLEN_P(new_entry) = str_len;
+ Z_STRVAL_P(new_entry) = estrndup(str, Z_STRLEN_P(new_entry));
+ Z_TYPE_P(new_entry) = IS_STRING;
- SAFE_RETURN;
+ register_raw_var_ex(var, new_entry, array TSRMLS_DC);
}
-static SAPI_POST_HANDLER_FUNC(rfc1867_post_handler_legacy)
+/*
+ * The combined READER/HANDLER
+ *
+ */
+
+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;
- zval *http_post_files=NULL; HashTable *uploaded_files=NULL;
-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
- int str_len = 0, num_vars = 0, num_vars_max = 2*10, *len_list = NULL;
- char **val_list = NULL;
-#endif
+ HashTable *uploaded_files=NULL;
+ HashTable *post_vars, *files_vars;
multipart_buffer *mbuff;
- zval *array_ptr = (zval *) arg;
int fd=-1;
zend_llist header;
void *event_extra_data = NULL;
@@ -1640,24 +653,18 @@ static SAPI_POST_HANDLER_FUNC(rfc1867_post_handler_legacy)
return;
}
- /* Initialize $_FILES[] */
- zend_hash_init(&PG(rfc1867_protected_variables), 5, NULL, NULL, 0);
-
ALLOC_HASHTABLE(uploaded_files);
zend_hash_init(uploaded_files, 5, NULL, (dtor_func_t) free_estring, 0);
SG(rfc1867_uploaded_files) = uploaded_files;
- ALLOC_ZVAL(http_post_files);
- array_init(http_post_files);
- INIT_PZVAL(http_post_files);
- PG(http_globals)[TRACK_VARS_FILES] = http_post_files;
+ ALLOC_HASHTABLE(post_vars);
+ zend_hash_init(post_vars, 5, NULL, ZVAL_PTR_DTOR, 0);
+ SG(rfc1867_vars) = post_vars;
+
+ ALLOC_HASHTABLE(files_vars);
+ zend_hash_init(files_vars, 5, NULL, ZVAL_PTR_DTOR, 0);
+ SG(rfc1867_files_vars) = files_vars;
-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
- if (php_mb_encoding_translation(TSRMLS_C)) {
- val_list = (char **)ecalloc(num_vars_max+2, sizeof(char *));
- len_list = (int *)ecalloc(num_vars_max+2, sizeof(int));
- }
-#endif
zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0);
if (php_rfc1867_callback != NULL) {
@@ -1724,41 +731,15 @@ static SAPI_POST_HANDLER_FUNC(rfc1867_post_handler_legacy)
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("");
+ value_len = 0;
}
- if (sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC)) {
- if (php_rfc1867_callback != NULL) {
- multipart_event_formdata event_formdata;
- size_t newlength = 0;
-
- event_formdata.post_bytes_processed = SG(read_post_bytes);
- event_formdata.name = ZSTR(param);
- event_formdata.value = PZSTR(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;
- }
+ register_raw_var(param, value, value_len, post_vars TSRMLS_DC);
-#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,
- &num_vars, &num_vars_max TSRMLS_CC);
- } else {
- safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
- }
-#else
- safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
-#endif
- } else if (php_rfc1867_callback != NULL) {
+ if (php_rfc1867_callback != NULL) {
multipart_event_formdata event_formdata;
event_formdata.post_bytes_processed = SG(read_post_bytes);
@@ -1976,35 +957,6 @@ static SAPI_POST_HANDLER_FUNC(rfc1867_post_handler_legacy)
llen = strlen(param) + MAX_SIZE_OF_INDEX + 1;
lbuf = (char *) emalloc(llen);
- if (is_arr_upload) {
- if (abuf) efree(abuf);
- abuf = estrndup(param, strlen(param)-array_len);
- snprintf(lbuf, llen, "%s_name[%s]", abuf, array_index);
- } else {
- snprintf(lbuf, llen, "%s_name", param);
- }
-
-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
- if (php_mb_encoding_translation(TSRMLS_C)) {
- if (num_vars>=num_vars_max){
- php_mb_gpc_realloc_buffer(&val_list, &len_list, &num_vars_max,
- 1 TSRMLS_CC);
- }
- 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, 1, NULL, NULL TSRMLS_CC);
- }
- s = php_mb_strrchr(filename, '\\' TSRMLS_CC);
- if ((tmp = php_mb_strrchr(filename, '/' TSRMLS_CC)) > s) {
- s = tmp;
- }
- num_vars--;
- goto filedone;
- }
-#endif
/* 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
@@ -2016,18 +968,6 @@ static SAPI_POST_HANDLER_FUNC(rfc1867_post_handler_legacy)
s = tmp;
}
-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
-filedone:
-#endif
-
- if (!is_anonymous) {
- if (s && s > filename) {
- safe_php_register_variable(lbuf, s+1, strlen(s+1), NULL, 0 TSRMLS_CC);
- } else {
- safe_php_register_variable(lbuf, filename, strlen(filename), NULL, 0 TSRMLS_CC);
- }
- }
-
/* Add $foo[name] */
if (is_arr_upload) {
snprintf(lbuf, llen, "%s[name][%s]", abuf, array_index);
@@ -2035,9 +975,9 @@ filedone:
snprintf(lbuf, llen, "%s[name]", param);
}
if (s && s > filename) {
- register_http_post_files_variable(lbuf, s+1, http_post_files, 0 TSRMLS_CC);
+ register_raw_var(lbuf, s+1, strlen(s+1), files_vars TSRMLS_CC);
} else {
- register_http_post_files_variable(lbuf, filename, http_post_files, 0 TSRMLS_CC);
+ register_raw_var(lbuf, filename, strlen(filename), files_vars TSRMLS_CC);
}
efree(filename);
s = NULL;
@@ -2053,23 +993,13 @@ filedone:
}
}
- /* Add $foo_type */
- if (is_arr_upload) {
- snprintf(lbuf, llen, "%s_type[%s]", abuf, array_index);
- } else {
- snprintf(lbuf, llen, "%s_type", param);
- }
- if (!is_anonymous) {
- safe_php_register_variable(lbuf, cd, strlen(cd), NULL, 0 TSRMLS_CC);
- }
-
/* Add $foo[type] */
if (is_arr_upload) {
snprintf(lbuf, llen, "%s[type][%s]", abuf, array_index);
} else {
snprintf(lbuf, llen, "%s[type]", param);
}
- register_http_post_files_variable(lbuf, cd, http_post_files, 0 TSRMLS_CC);
+ register_raw_var(lbuf, cd, strlen(cd), files_vars TSRMLS_CC);
/* Restore Content-Type Header */
if (s != NULL) {
@@ -2077,36 +1007,27 @@ filedone:
}
s = "";
- /* Initialize variables */
- add_protected_variable(param TSRMLS_CC);
-
- /* if param is of form xxx[.*] this will cut it to xxx */
- if (!is_anonymous) {
- safe_php_register_variable(param, temp_filename, strlen(temp_filename), NULL, 1 TSRMLS_CC);
- }
-
/* 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);
- register_http_post_files_variable(lbuf, temp_filename, http_post_files, 1 TSRMLS_CC);
+ register_raw_var(lbuf, temp_filename, strlen(temp_filename), files_vars TSRMLS_CC);
{
- zval file_size, error_type;
+ zval *file_size, *error_type;
+
+ MAKE_STD_ZVAL(error_type);
+ ZVAL_LONG(error_type, cancel_upload);
- error_type.value.lval = cancel_upload;
- error_type.type = IS_LONG;
+ MAKE_STD_ZVAL(file_size);
/* Add $foo[error] */
if (cancel_upload) {
- file_size.value.lval = 0;
- file_size.type = IS_LONG;
+ ZVAL_LONG(file_size, 0);
} else {
- file_size.value.lval = total_bytes;
- file_size.type = IS_LONG;
+ ZVAL_LONG(file_size, total_bytes);
}
if (is_arr_upload) {
@@ -2114,17 +1035,7 @@ filedone:
} else {
snprintf(lbuf, llen, "%s[error]", param);
}
- register_http_post_files_variable_ex(lbuf, &error_type, http_post_files, 0 TSRMLS_CC);
-
- /* Add $foo_size */
- if (is_arr_upload) {
- snprintf(lbuf, llen, "%s_size[%s]", abuf, array_index);
- } else {
- snprintf(lbuf, llen, "%s_size", param);
- }
- if (!is_anonymous) {
- safe_php_register_variable_ex(lbuf, &file_size, NULL, 0 TSRMLS_CC);
- }
+ register_raw_var_ex(lbuf, error_type, files_vars TSRMLS_CC);
/* Add $foo[size] */
if (is_arr_upload) {
@@ -2132,16 +1043,13 @@ filedone:
} else {
snprintf(lbuf, llen, "%s[size]", param);
}
- register_http_post_files_variable_ex(lbuf, &file_size, http_post_files, 0 TSRMLS_CC);
+ register_raw_var_ex(lbuf, file_size, files_vars TSRMLS_CC);
}
efree(param);
}
}
fileupload_done:
-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
- php_mb_flush_gpc_variables(num_vars, val_list, len_list, array_ptr TSRMLS_CC);
-#endif
if (php_rfc1867_callback != NULL) {
multipart_event_end event_end;
@@ -2154,16 +1062,6 @@ fileupload_done:
}
/*
- * The combined READER/HANDLER
- *
- */
-
-SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler)
-{
- rfc1867_post_handler_unicode(content_type_dup, arg TSRMLS_CC);
-}
-
-/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
diff --git a/sapi/apache/mod_php.c b/sapi/apache/mod_php.c
index b1b8153cf9..34c053042d 100644
--- a/sapi/apache/mod_php.c
+++ b/sapi/apache/mod_php.c
@@ -257,6 +257,7 @@ static void sapi_apache_register_server_variables(zval *track_vars_array TSRMLS_
zval **path_translated;
HashTable *symbol_table;
unsigned int new_val_len;
+ UConveter *conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
for (i = 0; i < arr->nelts; i++) {
char *val;
@@ -268,8 +269,9 @@ static void sapi_apache_register_server_variables(zval *track_vars_array TSRMLS_
val = "";
}
val_len = strlen(val);
- if (sapi_module.input_filter(PARSE_SERVER, elts[i].key, &val, val_len, &new_val_len TSRMLS_CC)) {
- php_register_variable_safe(elts[i].key, val, new_val_len, track_vars_array TSRMLS_CC);
+ if (php_register_variable_with_conv(conv, elts[i].key, strlen(elts[i].key), val,
+ val_len, track_vars_array, PARSE_SERVER TSRMLS_CC) == FAILURE) {
+ php_error(E_WARNING, "Failed to decode _SERVER array entry");
}
}
diff --git a/sapi/apache2filter/sapi_apache2.c b/sapi/apache2filter/sapi_apache2.c
index 609bf0c2a2..9e639fe8e5 100644
--- a/sapi/apache2filter/sapi_apache2.c
+++ b/sapi/apache2filter/sapi_apache2.c
@@ -234,19 +234,21 @@ php_apache_sapi_register_variables(zval *track_vars_array TSRMLS_DC)
const apr_array_header_t *arr = apr_table_elts(ctx->r->subprocess_env);
char *key, *val;
int new_val_len;
+ UConverter *conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
APR_ARRAY_FOREACH_OPEN(arr, key, val)
if (!val) {
val = "";
}
- if (sapi_module.input_filter(PARSE_SERVER, key, &val, strlen(val), &new_val_len TSRMLS_CC)) {
- php_register_variable_safe(key, val, new_val_len, track_vars_array TSRMLS_CC);
+ if (php_register_variable_with_conv(conv, key, strlen(key), val, strlen(val),
+ track_vars_array, PARSE_SERVER TSRMLS_CC) == FAILURE) {
+ php_error(E_WARNING, "Failed to decode _SERVER array entry");
}
APR_ARRAY_FOREACH_CLOSE()
- php_register_variable("PHP_SELF", ctx->r->uri, track_vars_array TSRMLS_CC);
- if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &ctx->r->uri, strlen(ctx->r->uri), &new_val_len TSRMLS_CC)) {
- php_register_variable_safe("PHP_SELF", ctx->r->uri, new_val_len, track_vars_array TSRMLS_CC);
+ if (php_register_variable_with_conv(conv, ZEND_STRL("PHP_SELF"), ctx->r->uri,
+ strlen(ctx->r->uri), track_vars_array, PARSE_SERVER TSRMLS_CC) == FAILURE) {
+ php_error(E_WARNING, "Failed to decode _SERVER array entry");
}
}
diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c
index 49fa7a5d00..6896af5052 100644
--- a/sapi/apache2handler/sapi_apache2.c
+++ b/sapi/apache2handler/sapi_apache2.c
@@ -250,19 +250,21 @@ php_apache_sapi_register_variables(zval *track_vars_array TSRMLS_DC)
php_struct *ctx = SG(server_context);
const apr_array_header_t *arr = apr_table_elts(ctx->r->subprocess_env);
char *key, *val;
- int new_val_len;
+ UConverter *conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
APR_ARRAY_FOREACH_OPEN(arr, key, val)
if (!val) {
val = "";
}
- if (sapi_module.input_filter(PARSE_SERVER, key, &val, strlen(val), &new_val_len TSRMLS_CC)) {
- php_register_variable_safe(key, val, new_val_len, track_vars_array TSRMLS_CC);
+ if (php_register_variable_with_conv(conv, key, strlen(key), val, strlen(val),
+ track_vars_array, PARSE_SERVER TSRMLS_CC) == FAILURE) {
+ php_error(E_WARNING, "Failed to decode _SERVER array entry");
}
APR_ARRAY_FOREACH_CLOSE()
- if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &ctx->r->uri, strlen(ctx->r->uri), &new_val_len TSRMLS_CC)) {
- php_register_variable_safe("PHP_SELF", ctx->r->uri, new_val_len, track_vars_array TSRMLS_CC);
+ if (php_register_variable_with_conv(conv, ZEND_STRL("PHP_SELF"), ctx->r->uri,
+ strlen(ctx->r->uri), track_vars_array, PARSE_SERVER TSRMLS_CC) == FAILURE) {
+ php_error(E_WARNING, "Failed to decode _SERVER array entry");
}
}
@@ -491,7 +493,7 @@ static void php_apache_ini_dtor(request_rec *r, request_rec *p TSRMLS_DC)
typedef struct {
HashTable config;
} php_conf_rec;
- char *str;
+ zstr str;
uint str_len;
php_conf_rec *c = ap_get_module_config(r->per_dir_config, &php6_module);
@@ -499,7 +501,7 @@ typedef struct {
zend_hash_get_current_key_ex(&c->config, &str, &str_len, NULL, 0, NULL) == HASH_KEY_IS_STRING;
zend_hash_move_forward(&c->config)
) {
- zend_restore_ini_entry(str, str_len, ZEND_INI_STAGE_SHUTDOWN);
+ zend_restore_ini_entry(str.s, str_len, ZEND_INI_STAGE_SHUTDOWN);
}
}
if (p) {
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index 64e29a99b0..af96789542 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -606,6 +606,7 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
char **val;
ulong idx;
int filter_arg = (array_ptr == PG(http_globals)[TRACK_VARS_ENV])?PARSE_ENV:PARSE_SERVER;
+ UConverter *conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
for (zend_hash_internal_pointer_reset_ex(request->env, &pos);
zend_hash_get_current_key_ex(request->env, &var, &var_len, &idx, 0, &pos) == HASH_KEY_IS_STRING &&
@@ -614,8 +615,9 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
) {
unsigned int new_val_len;
- if (sapi_module.input_filter(filter_arg, var.s, val, strlen(*val), &new_val_len TSRMLS_CC)) {
- php_register_variable_safe(var.s, *val, new_val_len, array_ptr TSRMLS_CC);
+ if (php_register_variable_with_conv(conv, var.s, strlen(var.s), val, strlen(*val),
+ array_ptr, filter_arg TSRMLS_CC) == FAILURE) {
+ php_error(E_WARNING, "Failed to decode %s array entry", (filter_arg == PARSE_ENV?"_ENV":"_SERVER"));
}
}
}
@@ -625,6 +627,7 @@ static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
{
unsigned int php_self_len;
char *php_self;
+ UConverter *conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv));
/* In CGI mode, we consider the environment to be a part of the server
* variables
@@ -648,15 +651,17 @@ static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
}
/* Build the special-case PHP_SELF variable for the CGI version */
- if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, php_self_len, &php_self_len TSRMLS_CC)) {
- php_register_variable_safe("PHP_SELF", php_self, php_self_len, track_vars_array TSRMLS_CC);
+ if (php_register_variable_with_conv(conv, ZEND_STRL("PHP_SELF"), php_self,
+ php_self_len, track_vars_array, PARSE_SERVER TSRMLS_CC) == FAILURE) {
+ php_error(E_WARNING, "Failed to decode _SERVER array entry");
}
efree(php_self);
} else {
php_self = SG(request_info).request_uri ? SG(request_info).request_uri : "";
php_self_len = strlen(php_self);
- if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, php_self_len, &php_self_len TSRMLS_CC)) {
- php_register_variable_safe("PHP_SELF", php_self, php_self_len, track_vars_array TSRMLS_CC);
+ if (php_register_variable_with_conv(conv, ZEND_STRL("PHP_SELF"), php_self,
+ php_self_len, track_vars_array, PARSE_SERVER TSRMLS_CC) == FAILURE) {
+ php_error(E_WARNING, "Failed to decode _SERVER array entry");
}
}
}
diff --git a/unicode-todo.txt b/unicode-todo.txt
index 8a664a679d..c58df1ccef 100644
--- a/unicode-todo.txt
+++ b/unicode-todo.txt
@@ -40,3 +40,6 @@
* See if ext/pcre can ba adjusted to allow operations on pure binary
strings. Ideal mode would be: convert all IS_UNICODE to UTF-8, assume that
binary strings with /u modifier are UTF-8, otherwise it's pure binary.
+
+* Optimize for zend_string_to_unicode() and zend_unicode_to_string() for
+ 0-length strings.