sas Wed Oct 2 23:23:02 2002 EDT
Modified files:
/php4/ext/session php_session.h session.c
Log:
Nuke PS(vars), we keep the state of registered session variables now
completely in PS(http_session_vars). This avoids bugs which are caused
by a lack of synchronization between the two hashes. We also don't need
to worry about prioritizing one of them.
Add session.bug_compat_42 and session.bug_compat_warn which are enabled
by default. The logic behind bug_compat_42:
IF bug_compat_42 is on, and
IF register_globals is off, and
IF any value of $_SESSION["key"] is NULL, and
IF there is a global variable $key, then
$_SESSION["key"] is set to $key.
The extension emits this warning once per script, unless told otherwise.
"Your script possibly relies on a session side-effect which existed until
PHP 4.2.3. Please be advised that the session extension does not consider
global variables as a source of data, unless register_globals is enabled.
You can disable this functionality and this warning by setting
session.bug_compat_42 or session.bug_compat_warn.
Index: php4/ext/session/php_session.h
diff -u php4/ext/session/php_session.h:1.82 php4/ext/session/php_session.h:1.83
--- php4/ext/session/php_session.h:1.82 Tue Oct 1 07:59:45 2002
+++ php4/ext/session/php_session.h Wed Oct 2 23:23:02 2002
@@ -103,12 +103,13 @@
zend_bool cookie_secure;
ps_module *mod;
void *mod_data;
- HashTable vars;
php_session_status session_status;
long gc_probability;
long gc_maxlifetime;
int module_number;
long cache_expire;
+ long bug_compat; /* Whether to behave like PHP 4.2 and earlier */
+ long bug_compat_warn; /* Whether to warn about it */
const struct ps_serializer_struct *serializer;
zval *http_session_vars;
zend_bool auto_start;
@@ -188,14 +189,12 @@
PHPAPI void php_session_start(TSRMLS_D);
#define PS_ADD_VARL(name,namelen) do {
\
- zend_hash_add_empty_element(&PS(vars), name, namelen + 1);
\
php_add_session_var(name, namelen TSRMLS_CC);
\
} while (0)
#define PS_ADD_VAR(name) PS_ADD_VARL(name, strlen(name))
#define PS_DEL_VARL(name,namelen) do {
\
- zend_hash_del(&PS(vars), name, namelen+1);
\
if (PS(http_session_vars)) {
\
zend_hash_del(Z_ARRVAL_P(PS(http_session_vars)), name, namelen+1);
\
}
\
@@ -210,7 +209,7 @@
#define PS_ENCODE_LOOP(code)
\
{
\
- HashTable *_ht = (PS(http_session_vars) ?
Z_ARRVAL_P(PS(http_session_vars)) : &PS(vars)); \
+ HashTable *_ht = Z_ARRVAL_P(PS(http_session_vars)); \
\
for (zend_hash_internal_pointer_reset(_ht); \
zend_hash_get_current_key_ex(_ht, &key, &key_length,
&num_key, 0, NULL) == HASH_KEY_IS_STRING; \
Index: php4/ext/session/session.c
diff -u php4/ext/session/session.c:1.324 php4/ext/session/session.c:1.325
--- php4/ext/session/session.c:1.324 Wed Oct 2 17:51:32 2002
+++ php4/ext/session/session.c Wed Oct 2 23:23:02 2002
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: session.c,v 1.324 2002/10/02 21:51:32 sas Exp $ */
+/* $Id: session.c,v 1.325 2002/10/03 03:23:02 sas Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -121,6 +121,8 @@
/* {{{ PHP_INI
*/
PHP_INI_BEGIN()
+ STD_PHP_INI_BOOLEAN("session.bug_compat_42", "1", PHP_INI_ALL,
+OnUpdateBool, bug_compat, php_ps_globals, ps_globals)
+ STD_PHP_INI_BOOLEAN("session.bug_compat_warn", "1", PHP_INI_ALL,
+OnUpdateBool, bug_compat_warn, php_ps_globals, ps_globals)
STD_PHP_INI_ENTRY("session.save_path", "/tmp", PHP_INI_ALL,
OnUpdateString, save_path, php_ps_globals, ps_globals)
STD_PHP_INI_ENTRY("session.name", "PHPSESSID", PHP_INI_ALL,
OnUpdateString, session_name, php_ps_globals, ps_globals)
PHP_INI_ENTRY("session.save_handler", "files", PHP_INI_ALL,
OnUpdateSaveHandler)
@@ -163,6 +165,9 @@
ps_user_ptr
};
+#define IF_SESSION_VARS() \
+ if (PS(http_session_vars) && PS(http_session_vars)->type == IS_ARRAY)
+
PHPAPI int php_session_register_serializer(const char *name,
int (*encode)(PS_SERIALIZER_ENCODE_ARGS),
int (*decode)(PS_SERIALIZER_DECODE_ARGS))
@@ -305,14 +310,14 @@
} else {
zend_set_hash_symbol(state_val, name, namelen, 1, 2,
Z_ARRVAL_P(PS(http_session_vars)), &EG(symbol_table));
}
- } else if (PS(http_session_vars)) {
+ } else IF_SESSION_VARS() {
zend_set_hash_symbol(state_val, name, namelen, 0, 1,
Z_ARRVAL_P(PS(http_session_vars)));
}
}
int php_get_session_var(char *name, size_t namelen, zval ***state_var TSRMLS_DC)
{
- if (PS(http_session_vars) && PS(http_session_vars)->type == IS_ARRAY) {
+ IF_SESSION_VARS() {
return zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name,
namelen+1, (void **) state_var);
}
@@ -483,14 +488,13 @@
{
char *ret = NULL;
- if (!PS(http_session_vars)) {
+ IF_SESSION_VARS() {
+ if (PS(serializer)->encode(&ret, newlen TSRMLS_CC) == FAILURE)
+ ret = NULL;
+ } else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot encode
non-existent session.");
- return NULL;
}
- if (PS(serializer)->encode(&ret, newlen TSRMLS_CC) == FAILURE)
- ret = NULL;
-
return ret;
}
@@ -586,33 +590,66 @@
}
}
-static void php_session_save_current_state(TSRMLS_D)
+static void migrate_global(HashTable *ht, HashPosition *pos TSRMLS_DC)
{
- char *val;
- int vallen;
- int ret = FAILURE;
- char *variable;
- uint variable_len;
+ char *str;
+ uint str_len;
ulong num_key;
- HashPosition pos;
+ int n;
+ zval **val = NULL;
- if (!PG(register_globals) && !PS(http_session_vars)) {
- return;
- }
-
- if (PS(http_session_vars) && PS(http_session_vars)->type != IS_ARRAY) {
- return;
+ n = zend_hash_get_current_key_ex(ht, &str, &str_len, &num_key, 0, pos);
+
+ switch (n) {
+ case HASH_KEY_IS_STRING:
+ zend_hash_find(&EG(symbol_table), str, str_len, (void **)
+&val);
+ if (val) {
+ ZEND_SET_SYMBOL_WITH_LENGTH(ht, str, str_len, *val, 1,
+0);
+ }
+ break;
+ case HASH_KEY_IS_LONG:
+ php_error(E_NOTICE, "The session bug compatibility code will
+not "
+ "try to locate the global variable $%d due to
+its "
+ "numeric nature.", num_key);
+ break;
}
-
- if (PS(http_session_vars)) {
- for
(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(PS(http_session_vars)), &pos);
-
zend_hash_get_current_key_ex(Z_ARRVAL_P(PS(http_session_vars)), &variable,
&variable_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING;
-
zend_hash_move_forward_ex(Z_ARRVAL_P(PS(http_session_vars)),&pos)) {
- PS_ADD_VARL(variable, variable_len-1);
+}
+
+static void php_session_save_current_state(TSRMLS_D)
+{
+ int ret = FAILURE;
+
+ IF_SESSION_VARS() {
+ if (PS(bug_compat) && !PG(register_globals)) {
+ HashTable *ht = Z_ARRVAL_P(PS(http_session_vars));
+ HashPosition pos;
+ zval **val;
+ int do_warn = 0;
+
+ zend_hash_internal_pointer_reset_ex(ht, &pos);
+
+ while (zend_hash_get_current_data_ex(ht,
+ (void **) &val, &pos) != FAILURE) {
+ if (Z_TYPE_PP(val) == IS_NULL) {
+ do_warn = 1;
+
+ migrate_global(ht, &pos);
+ }
+ zend_hash_move_forward_ex(ht, &pos);
+ }
+
+ if (do_warn && PS(bug_compat_warn)) {
+ php_error(E_WARNING, "Your script possibly relies on a
+session side-effect which existed until PHP 4.2.3. Please be advised that the session
+extension does not consider global variables as a source of data, unless
+register_globals is enabled. You can disable this functionality and this warning by
+setting session.bug_compat_42 or session.bug_compat_warn.");
+ }
}
+ } else {
+ return;
}
if (PS(mod_data)) {
+ char *val;
+ int vallen;
+
val = php_session_encode(&vallen TSRMLS_CC);
if (val) {
ret = PS(mod)->write(&PS(mod_data), PS(id), val, vallen
TSRMLS_CC);
@@ -1328,11 +1365,17 @@
convert_to_string_ex(p_name);
- if (zend_hash_find(&PS(vars), Z_STRVAL_PP(p_name),
- Z_STRLEN_PP(p_name)+1, (void **)&p_var) == SUCCESS)
- RETURN_TRUE
- else
+ if (PS(session_status) == php_session_none)
RETURN_FALSE;
+
+ IF_SESSION_VARS() {
+ if (zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)),
+ Z_STRVAL_PP(p_name), Z_STRLEN_PP(p_name)+1,
+ (void **)&p_var) == SUCCESS) {
+ RETURN_TRUE;
+ }
+ }
+ RETURN_FALSE;
}
/* }}} */
@@ -1402,25 +1445,30 @@
Unset all registered variables */
PHP_FUNCTION(session_unset)
{
- zval **tmp;
- char *variable;
- ulong num_key;
-
if (PS(session_status) == php_session_none)
RETURN_FALSE;
- if (PG(register_globals)) {
- for (zend_hash_internal_pointer_reset(&PS(vars));
- zend_hash_get_current_key(&PS(vars), &variable,
&num_key, 0) == HASH_KEY_IS_STRING;
- zend_hash_move_forward(&PS(vars))) {
- if (zend_hash_find(&EG(symbol_table), variable,
strlen(variable) + 1, (void **) &tmp)
- == SUCCESS)
- zend_hash_del(&EG(symbol_table), variable,
strlen(variable) + 1);
+ IF_SESSION_VARS() {
+ HashTable *ht = Z_ARRVAL_P(PS(http_session_vars));
+
+ if (PG(register_globals)) {
+ uint str_len;
+ char *str;
+ ulong num_key;
+ HashPosition pos;
+
+ zend_hash_internal_pointer_reset_ex(ht, &pos);
+
+ while (zend_hash_get_current_key_ex(ht, &str, &str_len,
+&num_key,
+ 0, &pos) == HASH_KEY_IS_STRING) {
+ zend_hash_del(&EG(symbol_table), str, str_len);
+ zend_hash_move_forward_ex(ht, &pos);
+ }
}
+
+ /* Clean $_SESSION. */
+ zend_hash_clean(ht);
}
-
- /* Clean $HTTP_SESSION_VARS. */
- zend_hash_clean(Z_ARRVAL_P(PS(http_session_vars)));
}
/* }}} */
@@ -1433,7 +1481,6 @@
static void php_rinit_session_globals(TSRMLS_D)
{
- zend_hash_init(&PS(vars), 0, NULL, NULL, 0);
PS(id) = NULL;
PS(session_status) = php_session_none;
PS(mod_data) = NULL;
@@ -1448,7 +1495,6 @@
if (PS(id)) {
efree(PS(id));
}
- zend_hash_destroy(&PS(vars));
}
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php