From 08caa5ac0051445077989810786fc3a41f7e390e Mon Sep 17 00:00:00 2001 From: Stefan Esser Date: Mon, 17 Feb 2014 21:34:51 +0100 Subject: Add some PHP 5.6.0aplha2 compatibility --- Changelog | 1 + post_handler.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- rfc1867_new.c | 2 +- session.c | 81 +++++++++++++++++++++++++++++++++++--- 4 files changed, 198 insertions(+), 8 deletions(-) diff --git a/Changelog b/Changelog index 1129c99..349c8e8 100644 --- a/Changelog +++ b/Changelog @@ -12,6 +12,7 @@ - Add ini_set() fail mode to suhosin.disable.display_errors - Fix suhosin.get/post/cookie.max_totalname_length filter - Refactor array index handling in filter to make it work always + - Added support for PHP 5.6.0alpha2 - TODO: WARN THAT FUNCTION WHITELISTS/BLACKLISTS NEVER WORKED CORRECTLY WITH PHP < 5.5 2012-02-12 - 0.9.34 diff --git a/post_handler.c b/post_handler.c index 7c678f4..4794a6b 100644 --- a/post_handler.c +++ b/post_handler.c @@ -32,10 +32,13 @@ #include "php_content_types.h" #include "suhosin_rfc1867.h" #include "ext/standard/url.h" +#include "ext/standard/php_smart_str.h" + SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler); +#if PHP_VERSION_ID < 50600 SAPI_POST_HANDLER_FUNC(suhosin_std_post_handler) { char *var, *val, *e, *s, *p; @@ -68,7 +71,7 @@ last_value: val_len = php_url_decode(val, (p - val)); val = estrndup(val, val_len); if (suhosin_input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { - if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) { + if (sapi_module.input_filter(PARSE_POST, var, &val, new_val_len, &new_val_len TSRMLS_CC)) { php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); } } else { @@ -83,6 +86,123 @@ last_value: goto last_value; } } +#else +typedef struct post_var_data { + smart_str str; + char *ptr; + char *end; + uint64_t cnt; +} post_var_data_t; + +static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof TSRMLS_DC) +{ + char *ksep, *vsep; + size_t klen, vlen; + /* FIXME: string-size_t */ + unsigned int new_vlen; + + if (var->ptr >= var->end) { + return 0; + } + + vsep = memchr(var->ptr, '&', var->end - var->ptr); + if (!vsep) { + if (!eof) { + return 0; + } else { + vsep = var->end; + } + } + + ksep = memchr(var->ptr, '=', vsep - var->ptr); + if (ksep) { + *ksep = '\0'; + /* "foo=bar&" or "foo=&" */ + klen = ksep - var->ptr; + vlen = vsep - ++ksep; + } else { + ksep = ""; + /* "foo&" */ + klen = vsep - var->ptr; + vlen = 0; + } + + + php_url_decode(var->ptr, klen); + if (vlen) { + vlen = php_url_decode(ksep, vlen); + } + + if (suhosin_input_filter(PARSE_POST, var->ptr, &ksep, vlen, &new_vlen TSRMLS_CC)) { + if (sapi_module.input_filter(PARSE_POST, var->ptr, &ksep, new_vlen, &new_vlen TSRMLS_CC)) { + php_register_variable_safe(var->ptr, ksep, new_vlen, arr TSRMLS_CC); + } + } else { + SUHOSIN_G(abort_request)=1; + } + + var->ptr = vsep + (vsep != var->end); + return 1; +} + +static inline int add_post_vars(zval *arr, post_var_data_t *vars, zend_bool eof TSRMLS_DC) +{ + uint64_t max_vars = PG(max_input_vars); + + vars->ptr = vars->str.c; + vars->end = vars->str.c + vars->str.len; + while (add_post_var(arr, vars, eof TSRMLS_CC)) { + if (++vars->cnt > max_vars) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Input variables exceeded %" PRIu64 ". " + "To increase the limit change max_input_vars in php.ini.", + max_vars); + return FAILURE; + } + } + + if (!eof) { + memmove(vars->str.c, vars->ptr, vars->str.len = vars->end - vars->ptr); + } + return SUCCESS; +} + +SAPI_POST_HANDLER_FUNC(suhosin_std_post_handler) +{ + zval *arr = (zval *) arg; + php_stream *s = SG(request_info).request_body; + post_var_data_t post_data; + + if (s && SUCCESS == php_stream_rewind(s)) { + memset(&post_data, 0, sizeof(post_data)); + + while (!php_stream_eof(s)) { + char buf[BUFSIZ] = {0}; + size_t len = php_stream_read(s, buf, BUFSIZ); + + if (len && len != (size_t) -1) { + smart_str_appendl(&post_data.str, buf, len); + + if (SUCCESS != add_post_vars(arr, &post_data, 0 TSRMLS_CC)) { + if (post_data.str.c) { + efree(post_data.str.c); + } + return; + } + } + + if (len != BUFSIZ){ + break; + } + } + + add_post_vars(arr, &post_data, 1 TSRMLS_CC); + if (post_data.str.c) { + efree(post_data.str.c); + } + } +} +#endif static void suhosin_post_handler_modification(sapi_post_entry *spe) { diff --git a/rfc1867_new.c b/rfc1867_new.c index 8ab0494..1d7ff9e 100644 --- a/rfc1867_new.c +++ b/rfc1867_new.c @@ -857,7 +857,7 @@ SAPI_POST_HANDLER_FUNC(suhosin_rfc1867_post_handler) /* {{{ */ continue; } - if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC)) { + if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, new_val_len, &new_val_len TSRMLS_CC)) { if (suhosin_rfc1867_filter != NULL) { multipart_event_formdata event_formdata; size_t newlength = new_val_len; diff --git a/session.c b/session.c index 3c40567..f6cff15 100644 --- a/session.c +++ b/session.c @@ -234,7 +234,7 @@ typedef struct _php_ps_globals_53 { } php_ps_globals_53; #if PHP_VERSION_ID >= 50400 -typedef struct _php_session_rfc1867_progress_54_55 { +typedef struct _php_session_rfc1867_progress_54_55_56 { size_t sname_len; zval sid; @@ -252,7 +252,7 @@ typedef struct _php_session_rfc1867_progress_54_55 { zval *files; /* data["files"] array */ zval *current_file; /* array of currently uploading file */ zval *current_file_bytes_processed; -} php_session_rfc1867_progress_54_55; +} php_session_rfc1867_progress_54_55_56; typedef struct _php_ps_globals_54 { char *save_path; @@ -306,7 +306,7 @@ typedef struct _php_ps_globals_54 { int define_sid; zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ - php_session_rfc1867_progress_54_55 *rfc1867_progress; + php_session_rfc1867_progress_54_55_56 *rfc1867_progress; zend_bool rfc1867_enabled; /* session.upload_progress.enabled */ zend_bool rfc1867_cleanup; /* session.upload_progress.cleanup */ smart_str rfc1867_prefix; /* session.upload_progress.prefix */ @@ -370,7 +370,7 @@ typedef struct _php_ps_globals_55 { int define_sid; zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ - php_session_rfc1867_progress_54_55 *rfc1867_progress; + php_session_rfc1867_progress_54_55_56 *rfc1867_progress; zend_bool rfc1867_enabled; /* session.upload_progress.enabled */ zend_bool rfc1867_cleanup; /* session.upload_progress.cleanup */ smart_str rfc1867_prefix; /* session.upload_progress.prefix */ @@ -380,11 +380,78 @@ typedef struct _php_ps_globals_55 { zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ } php_ps_globals_55; + +typedef struct _php_ps_globals_56 { + char *save_path; + char *session_name; + char *id; + char *extern_referer_chk; + char *entropy_file; + char *cache_limiter; + long entropy_length; + long cookie_lifetime; + char *cookie_path; + char *cookie_domain; + zend_bool cookie_secure; + zend_bool cookie_httponly; + ps_module *mod; + ps_module *default_mod; + void *mod_data; + php_session_status session_status; + long gc_probability; + long gc_divisor; + long gc_maxlifetime; + int module_number; + long cache_expire; + union { + zval *names[7]; + struct { + zval *ps_open; + zval *ps_close; + zval *ps_read; + zval *ps_write; + zval *ps_destroy; + zval *ps_gc; + zval *ps_create_sid; + } name; + } mod_user_names; + int mod_user_implemented; + int mod_user_is_open; + const struct ps_serializer_struct *serializer; + zval *http_session_vars; + zend_bool auto_start; + zend_bool use_cookies; + zend_bool use_only_cookies; + zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */ + zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */ + + long hash_func; +#if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH) + php_hash_ops *hash_ops; +#endif + long hash_bits_per_character; + int send_cookie; + int define_sid; + zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */ + + php_session_rfc1867_progress_54_55_56 *rfc1867_progress; + zend_bool rfc1867_enabled; /* session.upload_progress.enabled */ + zend_bool rfc1867_cleanup; /* session.upload_progress.cleanup */ + smart_str rfc1867_prefix; /* session.upload_progress.prefix */ + smart_str rfc1867_name; /* session.upload_progress.name */ + long rfc1867_freq; /* session.upload_progress.freq */ + double rfc1867_min_freq; /* session.upload_progress.min_freq */ + + zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */ + unsigned char session_data_hash[16]; /* binary MD5 hash length */ +} php_ps_globals_56; #endif #ifdef ZTS static ts_rsrc_id session_globals_id = 0; -# if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 5) +# if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 6) +# define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_56 *, v) +# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 5) # define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_55 *, v) # elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) # define SESSION_G(v) TSRMG(session_globals_id, php_ps_globals_54 *, v) @@ -400,7 +467,9 @@ static ts_rsrc_id session_globals_id = 0; UNSUPPORTED PHP VERSION # endif #else -# if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 5) +# if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 6) +static php_ps_globals_56 *session_globals = NULL; +# elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 5) static php_ps_globals_55 *session_globals = NULL; # elif (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) static php_ps_globals_54 *session_globals = NULL; -- cgit v1.3