diff options
Diffstat (limited to 'ext/session/session.c')
| -rw-r--r-- | ext/session/session.c | 90 |
1 files changed, 64 insertions, 26 deletions
diff --git a/ext/session/session.c b/ext/session/session.c index ea6b88f1d..2b4524687 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: session.c,v 1.417.2.8.2.16 2006/10/06 21:11:36 iliaa Exp $ */ +/* $Id: session.c,v 1.417.2.8.2.33 2007/04/04 19:52:19 tony2001 Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -153,13 +153,17 @@ static PHP_INI_MH(OnUpdateSaveDir) if (stage == PHP_INI_STAGE_RUNTIME) { char *p; + if (memchr(new_value, '\0', new_value_length) != NULL) { + return FAILURE; + } + if ((p = zend_memrchr(new_value, ';', new_value_length))) { p++; } else { p = new_value; } - if (PG(safe_mode) && (!php_checkuid(p, NULL, CHECKUID_ALLOW_ONLY_DIR))) { + if (PG(safe_mode) && (!php_checkuid(p, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { return FAILURE; } @@ -272,7 +276,7 @@ PHP_MINFO_FUNCTION(session); static void php_rinit_session_globals(TSRMLS_D); static void php_rshutdown_session_globals(TSRMLS_D); -static zend_bool php_session_destroy(TSRMLS_D); +static int php_session_destroy(TSRMLS_D); zend_module_entry session_module_entry = { STANDARD_MODULE_HEADER, @@ -324,9 +328,12 @@ PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) if (PG(register_globals)) { zval **sym_global = NULL; - zend_hash_find(&EG(symbol_table), name, namelen + 1, - (void *) &sym_global); - + if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void *) &sym_global) == SUCCESS) { + if ((Z_TYPE_PP(sym_global) == IS_ARRAY && Z_ARRVAL_PP(sym_global) == &EG(symbol_table)) || *sym_global == PS(http_session_vars)) { + return; + } + } + if (sym_global == NULL && sym_track == NULL) { zval *empty_var; @@ -356,7 +363,10 @@ PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php if (PG(register_globals)) { zval **old_symbol; if (zend_hash_find(&EG(symbol_table),name,namelen+1,(void *)&old_symbol) == SUCCESS) { - + if ((Z_TYPE_PP(old_symbol) == IS_ARRAY && Z_ARRVAL_PP(old_symbol) == &EG(symbol_table)) || *old_symbol == PS(http_session_vars)) { + return; + } + /* * A global symbol with the same name exists already. That * symbol might have been created by other means (e.g. $_GET). @@ -465,13 +475,26 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) PHP_VAR_UNSERIALIZE_INIT(var_hash); for (p = val; p < endptr; ) { + zval **tmp; namelen = *p & (~PS_BIN_UNDEF); + + if (namelen < 0 || namelen > PS_BIN_MAX || (p + namelen) >= endptr) { + return FAILURE; + } + has_value = *p & PS_BIN_UNDEF ? 0 : 1; name = estrndup(p + 1, namelen); - + p += namelen + 1; - + + if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) { + if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == &EG(symbol_table)) || *tmp == PS(http_session_vars)) { + efree(name); + continue; + } + } + if (has_value) { ALLOC_INIT_ZVAL(current); if (php_var_unserialize(¤t, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { @@ -500,7 +523,7 @@ PS_SERIALIZER_ENCODE_FUNC(php) PHP_VAR_SERIALIZE_INIT(var_hash); PS_ENCODE_LOOP( - smart_str_appendl(&buf, key, (unsigned char) key_length); + smart_str_appendl(&buf, key, key_length); if (memchr(key, PS_DELIMITER, key_length)) { PHP_VAR_SERIALIZE_DESTROY(var_hash); smart_str_free(&buf); @@ -537,6 +560,7 @@ PS_SERIALIZER_DECODE_FUNC(php) p = val; while (p < endptr) { + zval **tmp; q = p; while (*q != PS_DELIMITER) if (++q >= endptr) goto break_outer_loop; @@ -551,17 +575,23 @@ PS_SERIALIZER_DECODE_FUNC(php) namelen = q - p; name = estrndup(p, namelen); q++; - + + if (zend_hash_find(&EG(symbol_table), name, namelen + 1, (void **) &tmp) == SUCCESS) { + if ((Z_TYPE_PP(tmp) == IS_ARRAY && Z_ARRVAL_PP(tmp) == &EG(symbol_table)) || *tmp == PS(http_session_vars)) { + goto skip; + } + } + if (has_value) { ALLOC_INIT_ZVAL(current); if (php_var_unserialize(¤t, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { - php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC); + php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC); } zval_ptr_dtor(¤t); } PS_ADD_VARL(name, namelen); +skip: efree(name); - p = q; } break_outer_loop: @@ -579,16 +609,20 @@ static void php_session_track_init(TSRMLS_D) zend_delete_global_variable("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS")-1 TSRMLS_CC); zend_delete_global_variable("_SESSION", sizeof("_SESSION")-1 TSRMLS_CC); + if (PS(http_session_vars)) { + zval_ptr_dtor(&PS(http_session_vars)); + } + MAKE_STD_ZVAL(session_vars); array_init(session_vars); PS(http_session_vars) = session_vars; if (PG(register_long_arrays)) { - ZEND_SET_GLOBAL_VAR_WITH_LENGTH("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), PS(http_session_vars), 2, 1); - ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 2, 1); + ZEND_SET_GLOBAL_VAR_WITH_LENGTH("HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), PS(http_session_vars), 3, 1); + ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 3, 1); } else { - ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 1, 0); + ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 2, 1); } } @@ -697,10 +731,8 @@ PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) remote_addr = Z_STRVAL_PP(token); } - buf = emalloc(100); - /* maximum 15+19+19+10 bytes */ - sprintf(buf, "%.15s%ld%ld%0.8f", remote_addr ? remote_addr : "", + spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10); switch (PS(hash_func)) { @@ -814,6 +846,7 @@ new_session: } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */ PS(invalid_session_id) = 0; efree(PS(id)); + PS(id) = NULL; goto new_session; } } @@ -918,7 +951,7 @@ static void strcpy_gmt(char *ubuf, time_t *when) php_gmtime_r(when, &tm); - n = sprintf(buf, "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */ + n = slprintf(buf, sizeof(buf), "%s, %02d %s %d %02d:%02d:%02d GMT", /* SAFE */ week_days[tm.tm_wday], tm.tm_mday, month_names[tm.tm_mon], tm.tm_year + 1900, tm.tm_hour, tm.tm_min, @@ -963,7 +996,7 @@ CACHE_LIMITER_FUNC(public) strcpy_gmt(buf + sizeof(EXPIRES) - 1, &now); ADD_HEADER(buf); - sprintf(buf, "Cache-Control: public, max-age=%ld", PS(cache_expire) * 60); /* SAFE */ + snprintf(buf, sizeof(buf) , "Cache-Control: public, max-age=%ld", PS(cache_expire) * 60); /* SAFE */ ADD_HEADER(buf); last_modified(TSRMLS_C); @@ -973,7 +1006,7 @@ CACHE_LIMITER_FUNC(private_no_expire) { char buf[MAX_STR + 1]; - sprintf(buf, "Cache-Control: private, max-age=%ld, pre-check=%ld", PS(cache_expire) * 60, PS(cache_expire) * 60); /* SAFE */ + snprintf(buf, sizeof(buf), "Cache-Control: private, max-age=%ld, pre-check=%ld", PS(cache_expire) * 60, PS(cache_expire) * 60); /* SAFE */ ADD_HEADER(buf); last_modified(TSRMLS_C); @@ -1300,9 +1333,9 @@ PHPAPI void php_session_start(TSRMLS_D) } } -static zend_bool php_session_destroy(TSRMLS_D) +static int php_session_destroy(TSRMLS_D) { - zend_bool retval = SUCCESS; + int retval = SUCCESS; if (PS(session_status) != php_session_active) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to destroy uninitialized session"); @@ -1528,7 +1561,7 @@ PHP_FUNCTION(session_regenerate_id) zend_bool del_ses = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) { - WRONG_PARAM_COUNT; + return; } if (SG(headers_sent)) { @@ -1543,6 +1576,7 @@ PHP_FUNCTION(session_regenerate_id) RETURN_FALSE; } efree(PS(id)); + PS(id) = NULL; } PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC); @@ -1824,6 +1858,10 @@ static void php_rinit_session_globals(TSRMLS_D) static void php_rshutdown_session_globals(TSRMLS_D) { + if (PS(http_session_vars)) { + zval_ptr_dtor(&PS(http_session_vars)); + PS(http_session_vars) = NULL; + } if (PS(mod_data)) { zend_try { PS(mod)->s_close(&PS(mod_data) TSRMLS_CC); |
