Browse Source

Implement JIT request decoding support for $_GET and $_POST.

experimental/first_unicode_implementation
Andrei Zmievski 17 years ago
parent
commit
afa4e41c2f
  1. 25
      Zend/zend.c
  2. 16
      Zend/zend_compile.c
  3. 2
      Zend/zend_compile.h
  4. 3
      Zend/zend_globals.h
  5. 16
      ext/filter/filter.c
  6. 2
      ext/mbstring/mb_gpc.c
  7. 2
      ext/pcre/php_pcre.c
  8. 59
      ext/standard/basic_functions.c
  9. 4
      ext/standard/basic_functions.h
  10. 4
      ext/standard/php_string.h
  11. 8
      ext/standard/string.c
  12. 19
      main/SAPI.c
  13. 4
      main/SAPI.h
  14. 2
      main/php_globals.h
  15. 403
      main/php_variables.c
  16. 4
      main/php_variables.h
  17. 1214
      main/rfc1867.c
  18. 6
      sapi/apache/mod_php.c
  19. 12
      sapi/apache2filter/sapi_apache2.c
  20. 16
      sapi/apache2handler/sapi_apache2.c
  21. 17
      sapi/cgi/cgi_main.c
  22. 3
      unicode-todo.txt

25
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));
}

16
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) /* {{{ */

2
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);

3
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];

16
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) \

2
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);

2
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;

59
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

4
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);

4
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);

8
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;

19
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;

4
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;

2
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;
};

403
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);
}
/*

4
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()

1214
main/rfc1867.c
File diff suppressed because it is too large
View File

6
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");
}
}

12
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");
}
}

16
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) {

17
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");
}
}
}

3
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.
Loading…
Cancel
Save