diff options
Diffstat (limited to 'ext/session/session.c')
| -rw-r--r-- | ext/session/session.c | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/ext/session/session.c b/ext/session/session.c index eb14e07b65..6412043673 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -513,8 +513,17 @@ static void php_session_initialize(TSRMLS_D) /* {{{ */ PS(session_status) = php_session_active; } if (val) { + PHP_MD5_CTX context; + + /* Store read data's MD5 hash */ + PHP_MD5Init(&context); + PHP_MD5Update(&context, val, vallen); + PHP_MD5Final(PS(session_data_hash), &context); + php_session_decode(val, vallen TSRMLS_CC); - efree(val); + str_efree(val); + } else { + memset(PS(session_data_hash),'\0', 16); } if (!PS(use_cookies) && PS(send_cookie)) { @@ -537,7 +546,19 @@ static void php_session_save_current_state(TSRMLS_D) /* {{{ */ val = php_session_encode(&vallen TSRMLS_CC); if (val) { - ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC); + PHP_MD5_CTX context; + unsigned char digest[16]; + + /* Generate data's MD5 hash */ + PHP_MD5Init(&context); + PHP_MD5Update(&context, val, vallen); + PHP_MD5Final(digest, &context); + /* Write only when save is required */ + if (memcmp(digest, PS(session_data_hash), 16)) { + ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC); + } else { + ret = SUCCESS; + } efree(val); } else { ret = PS(mod)->s_write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC); @@ -734,6 +755,7 @@ static PHP_INI_MH(OnUpdateHashFunc) /* {{{ */ } #endif /* HAVE_HASH_EXT }}} */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "session.configuration 'session.hash_function' must be existing hash function. %s does not exist.", new_value); return FAILURE; } /* }}} */ @@ -1620,6 +1642,26 @@ static void php_session_flush(TSRMLS_D) /* {{{ */ } /* }}} */ +static void php_session_abort(TSRMLS_D) /* {{{ */ +{ + if (PS(session_status) == php_session_active) { + PS(session_status) = php_session_none; + if (PS(mod_data) || PS(mod_user_implemented)) { + PS(mod)->s_close(&PS(mod_data) TSRMLS_CC); + } + } +} +/* }}} */ + +static void php_session_reset(TSRMLS_D) /* {{{ */ +{ + if (PS(session_status) == php_session_active) { + php_session_initialize(TSRMLS_C); + } +} +/* }}} */ + + PHPAPI void session_adapt_url(const char *url, size_t urllen, char **new, size_t *newlen TSRMLS_DC) /* {{{ */ { if (PS(apply_trans_sid) && (PS(session_status) == php_session_active)) { @@ -2101,6 +2143,22 @@ static PHP_FUNCTION(session_write_close) } /* }}} */ +/* {{{ proto void session_abort(void) + Abort session and end session. Session data will not be written */ +static PHP_FUNCTION(session_abort) +{ + php_session_abort(TSRMLS_C); +} +/* }}} */ + +/* {{{ proto void session_reset(void) + Reset session data from saved session data */ +static PHP_FUNCTION(session_reset) +{ + php_session_reset(TSRMLS_C); +} +/* }}} */ + /* {{{ proto int session_status(void) Returns the current session status */ static PHP_FUNCTION(session_status) @@ -2252,6 +2310,8 @@ static const zend_function_entry session_functions[] = { PHP_FE(session_set_cookie_params, arginfo_session_set_cookie_params) PHP_FE(session_get_cookie_params, arginfo_session_void) PHP_FE(session_write_close, arginfo_session_void) + PHP_FE(session_abort, arginfo_session_void) + PHP_FE(session_reset, arginfo_session_void) PHP_FE(session_status, arginfo_session_void) PHP_FE(session_register_shutdown, arginfo_session_void) PHP_FALIAS(session_commit, session_write_close, arginfo_session_void) |
