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

Reply via email to