]> granicus.if.org Git - php/commitdiff
Refactor session (incompleted)
authorXinchen Hui <laruence@gmail.com>
Fri, 28 Mar 2014 10:46:25 +0000 (18:46 +0800)
committerXinchen Hui <laruence@gmail.com>
Fri, 28 Mar 2014 10:46:25 +0000 (18:46 +0800)
Zend/zend_API.c
ext/session/mod_files.c
ext/session/mod_user.c
ext/session/mod_user_class.c
ext/session/php_session.h
ext/session/session.c
ext/standard/url_scanner_ex.c
ext/standard/url_scanner_ex.re

index bcca30e1a313b61ad8b8b9ee1d2f8f6ed4c1dc29..f923740fbd89af9d7bedb7fa482c5606ba2c5cc1 100644 (file)
@@ -2716,7 +2716,9 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt
        while (num_symbol_tables-- > 0) {
                symbol_table = va_arg(symbol_table_list, HashTable *);
                zend_hash_str_update(symbol_table, name, name_length, symbol);
-               Z_ADDREF_P(symbol);
+               if (Z_REFCOUNTED_P(symbol)) {
+                       Z_ADDREF_P(symbol);
+               }
        }
        va_end(symbol_table_list);
        return SUCCESS;
index 4d5a18b36be5f27db1192d1ff5beae2ced5bafc4..ddfb62ab6c7a547c3ef1198cce757bf302909fdb 100644 (file)
@@ -328,13 +328,13 @@ PS_READ_FUNC(files)
 
        /* If strict mode, check session id existence */
        if (PS(use_strict_mode) &&
-               ps_files_key_exists(data, key TSRMLS_CC) == FAILURE) {
+               ps_files_key_exists(data, key? key->val : NULL TSRMLS_CC) == FAILURE) {
                /* key points to PS(id), but cannot change here. */
                if (key) {
-                       efree(PS(id));
+                       STR_RELEASE(PS(id));
                        PS(id) = NULL;
                }
-               PS(id) = PS(mod)->s_create_sid((void **)&data, NULL TSRMLS_CC);
+               PS(id) = PS(mod)->s_create_sid((void **)&data TSRMLS_CC);
                if (!PS(id)) {
                        return FAILURE;
                }
@@ -345,7 +345,7 @@ PS_READ_FUNC(files)
                PS(session_status) = php_session_active;
        }
 
-       ps_files_open(data, PS(id) TSRMLS_CC);
+       ps_files_open(data, PS(id)->val TSRMLS_CC);
        if (data->fd < 0) {
                return FAILURE;
        }
@@ -354,20 +354,20 @@ PS_READ_FUNC(files)
                return FAILURE;
        }
 
-       data->st_size = *vallen = sbuf.st_size;
+       data->st_size = sbuf.st_size;
 
        if (sbuf.st_size == 0) {
                *val = STR_EMPTY_ALLOC();
                return SUCCESS;
        }
 
-       *val = emalloc(sbuf.st_size);
+       *val = STR_ALLOC(sbuf.st_size, 0);
 
 #if defined(HAVE_PREAD)
-       n = pread(data->fd, *val, sbuf.st_size, 0);
+       n = pread(data->fd, (*val)->val, (*val)->len, 0);
 #else
        lseek(data->fd, 0, SEEK_SET);
-       n = read(data->fd, *val, sbuf.st_size);
+       n = read(data->fd, (*val)->val, (*val)->len);
 #endif
 
        if (n != sbuf.st_size) {
@@ -376,7 +376,7 @@ PS_READ_FUNC(files)
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "read returned less bytes than requested");
                }
-               efree(*val);
+               STR_RELEASE(*val);
                return FAILURE;
        }
 
@@ -388,25 +388,25 @@ PS_WRITE_FUNC(files)
        long n;
        PS_FILES_DATA;
 
-       ps_files_open(data, key TSRMLS_CC);
+       ps_files_open(data, key->val TSRMLS_CC);
        if (data->fd < 0) {
                return FAILURE;
        }
 
        /* Truncate file if the amount of new data is smaller than the existing data set. */
 
-       if (vallen < (int)data->st_size) {
+       if (val->len < (int)data->st_size) {
                php_ignore_value(ftruncate(data->fd, 0));
        }
 
 #if defined(HAVE_PWRITE)
-       n = pwrite(data->fd, val, vallen, 0);
+       n = pwrite(data->fd, val->val, val->len, 0);
 #else
        lseek(data->fd, 0, SEEK_SET);
-       n = write(data->fd, val, vallen);
+       n = write(data->fd, val->val, val->len);
 #endif
 
-       if (n != vallen) {
+       if (n != val->len) {
                if (n == -1) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "write failed: %s (%d)", strerror(errno), errno);
                } else {
@@ -423,7 +423,7 @@ PS_DESTROY_FUNC(files)
        char buf[MAXPATHLEN];
        PS_FILES_DATA;
 
-       if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
+       if (!ps_files_path_create(buf, sizeof(buf), data, key->val)) {
                return FAILURE;
        }
 
@@ -459,16 +459,16 @@ PS_GC_FUNC(files)
 
 PS_CREATE_SID_FUNC(files)
 {
-       char *sid;
+       zend_string *sid;
        int maxfail = 3;
        PS_FILES_DATA;
 
        do {
-               sid = php_session_create_id((void **)&data, newlen TSRMLS_CC);
+               sid = php_session_create_id(&data TSRMLS_C);
                /* Check collision */
-               if (data && ps_files_key_exists(data, sid TSRMLS_CC) == SUCCESS) {
+               if (data && ps_files_key_exists(data, sid? sid->val : NULL TSRMLS_CC) == SUCCESS) {
                        if (sid) {
-                               efree(sid);
+                               STR_RELEASE(sid);
                                sid = NULL;
                        }
                        if (!(maxfail--)) {
index 5573d4cdfd7338bbaca9aa5fea5fe6c1ff910d94..4e42a1ba142fa39108b63e92b0654a75774db880 100644 (file)
@@ -28,7 +28,6 @@ ps_module ps_mod_user = {
 
 #define SESS_ZVAL_LONG(val, a)                                         \
 {                                                                                                      \
-       MAKE_STD_ZVAL(a);                                                               \
        ZVAL_LONG(a, val);                                                              \
 }
 
@@ -40,58 +39,53 @@ ps_module ps_mod_user = {
 
 #define SESS_ZVAL_STRINGN(vl, ln, a)                           \
 {                                                                                                      \
-       MAKE_STD_ZVAL(a);                                                               \
-       ZVAL_STRINGL(a, vl, ln, 1);                                             \
+       ZVAL_STRINGL(a, vl, ln);                                                \
 }
 
-static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
+#define SESS_ZVAL_STR(vl, a)                                           \
+{                                                                                                      \
+       ZVAL_STR(a, STR_COPY(vl));                                              \
+}
+
+static void ps_call_handler(zval *func, int argc, zval *argv, zval *retval TSRMLS_DC)
 {
        int i;
-       zval *retval = NULL;
-
-       MAKE_STD_ZVAL(retval);
-       if (call_user_function(EG(function_table), NULL, func, retval, argc, argv TSRMLS_CC) == FAILURE) {
-               zval_ptr_dtor(&retval);
-               retval = NULL;
-       }
-
+       call_user_function(EG(function_table), NULL, func, retval, argc, argv TSRMLS_CC);
        for (i = 0; i < argc; i++) {
                zval_ptr_dtor(&argv[i]);
        }
-
-       return retval;
 }
 
 #define STDVARS                                                                \
-       zval *retval = NULL;                                    \
+       zval retval;                                                    \
        int ret = FAILURE
 
 #define PSF(a) PS(mod_user_names).name.ps_##a
 
 #define FINISH                                                         \
-       if (retval) {                                                   \
-               convert_to_long(retval);                        \
-               ret = Z_LVAL_P(retval);                         \
+       if (!ZVAL_IS_UNDEF(&retval)) {                  \
+               convert_to_long(&retval);                       \
+               ret = Z_LVAL(retval);                           \
                zval_ptr_dtor(&retval);                         \
        }                                                                               \
        return ret
 
 PS_OPEN_FUNC(user)
 {
-       zval *args[2];
+       zval args[2];
        STDVARS;
        
-       if (PSF(open) == NULL) {
+       if (ZVAL_IS_UNDEF(&PSF(open))) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING,
                        "user session functions not defined");
                        
                return FAILURE;
        }
 
-       SESS_ZVAL_STRING((char*)save_path, args[0]);
-       SESS_ZVAL_STRING((char*)session_name, args[1]);
+       SESS_ZVAL_STRING((char*)save_path, &args[0]);
+       SESS_ZVAL_STRING((char*)session_name, &args[1]);
 
-       retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC);
+       ps_call_handler(&PSF(open), 2, args, &retval TSRMLS_CC);
        PS(mod_user_implemented) = 1;
 
        FINISH;
@@ -108,7 +102,7 @@ PS_CLOSE_FUNC(user)
        }
 
        zend_try {
-               retval = ps_call_handler(PSF(close), 0, NULL TSRMLS_CC);
+               ps_call_handler(&PSF(close), 0, NULL, &retval TSRMLS_CC);
        } zend_catch {
                bailout = 1;
        } zend_end_try();
@@ -116,7 +110,7 @@ PS_CLOSE_FUNC(user)
        PS(mod_user_implemented) = 0;
 
        if (bailout) {
-               if (retval) {
+               if (!ZVAL_IS_UNDEF(&retval)) {
                        zval_ptr_dtor(&retval);
                }
                zend_bailout();
@@ -127,17 +121,16 @@ PS_CLOSE_FUNC(user)
 
 PS_READ_FUNC(user)
 {
-       zval *args[1];
+       zval args[1];
        STDVARS;
 
-       SESS_ZVAL_STRING((char*)key, args[0]);
+       SESS_ZVAL_STR(key, &args[0]);
 
-       retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC);
+       ps_call_handler(&PSF(read), 1, args, &retval TSRMLS_CC);
 
-       if (retval) {
-               if (Z_TYPE_P(retval) == IS_STRING) {
-                       *val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
-                       *vallen = Z_STRLEN_P(retval);
+       if (!ZVAL_IS_UNDEF(&retval)) {
+               if (Z_TYPE(retval) == IS_STRING) {
+                       *val = STR_COPY(Z_STR(retval));
                        ret = SUCCESS;
                }
                zval_ptr_dtor(&retval);
@@ -148,37 +141,37 @@ PS_READ_FUNC(user)
 
 PS_WRITE_FUNC(user)
 {
-       zval *args[2];
+       zval args[2];
        STDVARS;
 
-       SESS_ZVAL_STRING((char*)key, args[0]);
-       SESS_ZVAL_STRINGN((char*)val, vallen, args[1]);
+       SESS_ZVAL_STR(key, &args[0]);
+       SESS_ZVAL_STR(val, &args[1]);
 
-       retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC);
+       ps_call_handler(&PSF(write), 2, args, &retval TSRMLS_CC);
 
        FINISH;
 }
 
 PS_DESTROY_FUNC(user)
 {
-       zval *args[1];
+       zval args[1];
        STDVARS;
 
-       SESS_ZVAL_STRING((char*)key, args[0]);
+       SESS_ZVAL_STR(key, &args[0]);
 
-       retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC);
+       ps_call_handler(&PSF(destroy), 1, args, &retval TSRMLS_CC);
 
        FINISH;
 }
 
 PS_GC_FUNC(user)
 {
-       zval *args[1];
+       zval args[1];
        STDVARS;
 
-       SESS_ZVAL_LONG(maxlifetime, args[0]);
+       SESS_ZVAL_LONG(maxlifetime, &args[0]);
 
-       retval = ps_call_handler(PSF(gc), 1, args TSRMLS_CC);
+       ps_call_handler(&PSF(gc), 1, args, &retval TSRMLS_CC);
 
        FINISH;
 }
@@ -186,19 +179,18 @@ PS_GC_FUNC(user)
 PS_CREATE_SID_FUNC(user)
 {
        /* maintain backwards compatibility */
-       if (PSF(create_sid) != NULL) {
-               char *id = NULL;
-               zval *retval = NULL;
+       if (!ZVAL_IS_UNDEF(&PSF(create_sid))) {
+               zend_string *id = NULL;
+               zval retval;
 
-               retval = ps_call_handler(PSF(create_sid), 0, NULL TSRMLS_CC);
+               ps_call_handler(&PSF(create_sid), 0, NULL, &retval TSRMLS_CC);
 
-               if (retval) {
-                       if (Z_TYPE_P(retval) == IS_STRING) {
-                               id = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
+               if (!ZVAL_IS_UNDEF(&retval)) {
+                       if (Z_TYPE(retval) == IS_STRING) {
+                               id = STR_COPY(Z_STR(retval));
                        }
                        zval_ptr_dtor(&retval);
-               }
-               else {
+               } else {
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "No session id returned by function");
                        return NULL;
                }
@@ -212,7 +204,7 @@ PS_CREATE_SID_FUNC(user)
        }
 
        /* function as defined by PS_MOD */
-       return php_session_create_id(mod_data, newlen TSRMLS_CC);
+       return php_session_create_id(mod_data TSRMLS_CC);
 }
 
 /*
index b5b51da1292978ab065bb624149c274beff7dd52..78b90f49fa543649dad22b1db4be61f1acc23911 100644 (file)
@@ -71,23 +71,21 @@ PHP_METHOD(SessionHandler, close)
    Wraps the old read handler */
 PHP_METHOD(SessionHandler, read)
 {
-       char *key, *val;
-       int key_len, val_len;
+       zend_string *val;
+       zend_string *key;
 
        PS_SANITY_CHECK_IS_OPEN;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &key) == FAILURE) {
                return;
        }
 
-       if (PS(default_mod)->s_read(&PS(mod_data), key, &val, &val_len TSRMLS_CC) == FAILURE) {
+       if (PS(default_mod)->s_read(&PS(mod_data), key, &val TSRMLS_CC) == FAILURE) {
                RETVAL_FALSE;
                return;
        }
 
-       RETVAL_STRINGL(val, val_len);
-       efree(val);
-       return;
+       RETURN_STR(val);
 }
 /* }}} */
 
@@ -95,16 +93,15 @@ PHP_METHOD(SessionHandler, read)
    Wraps the old write handler */
 PHP_METHOD(SessionHandler, write)
 {
-       char *key, *val;
-       int key_len, val_len;
+       zend_string *key, *val;
 
        PS_SANITY_CHECK_IS_OPEN;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &key, &key_len, &val, &val_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "SS", &key, &val) == FAILURE) {
                return;
        }
 
-       RETVAL_BOOL(SUCCESS == PS(default_mod)->s_write(&PS(mod_data), key, val, val_len TSRMLS_CC));
+       RETURN_BOOL(SUCCESS == PS(default_mod)->s_write(&PS(mod_data), key, val TSRMLS_CC));
 }
 /* }}} */
 
@@ -112,16 +109,15 @@ PHP_METHOD(SessionHandler, write)
    Wraps the old destroy handler */
 PHP_METHOD(SessionHandler, destroy)
 {
-       char *key;
-       int key_len;
+       zend_string *key;
 
        PS_SANITY_CHECK_IS_OPEN;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &key) == FAILURE) {
                return;
        }
        
-       RETVAL_BOOL(SUCCESS == PS(default_mod)->s_destroy(&PS(mod_data), key TSRMLS_CC));
+       RETURN_BOOL(SUCCESS == PS(default_mod)->s_destroy(&PS(mod_data), key TSRMLS_CC));
 }
 /* }}} */
 
@@ -138,7 +134,7 @@ PHP_METHOD(SessionHandler, gc)
                return;
        }
        
-       RETVAL_BOOL(SUCCESS == PS(default_mod)->s_gc(&PS(mod_data), maxlifetime, &nrdels TSRMLS_CC));
+       RETURN_BOOL(SUCCESS == PS(default_mod)->s_gc(&PS(mod_data), maxlifetime, &nrdels TSRMLS_CC));
 }
 /* }}} */
 
@@ -146,16 +142,14 @@ PHP_METHOD(SessionHandler, gc)
    Wraps the old create_sid handler */
 PHP_METHOD(SessionHandler, create_sid)
 {
-       char *id;
+       zend_string *id;
 
        if (zend_parse_parameters_none() == FAILURE) {
            return;
        }
 
-       id = PS(default_mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
+       id = PS(default_mod)->s_create_sid(&PS(mod_data) TSRMLS_CC);
 
-       //????
-       RETVAL_STRING(id);
-       efree(id);
+       RETURN_STR(id);
 }
 /* }}} */
index 0f402080ca8220dc35b994384ba5cd4e8a22992a..b50a35a1c4bffb886a18cb8064b12658ca2db96e 100644 (file)
@@ -34,9 +34,9 @@
 
 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
-#define PS_READ_ARGS void **mod_data, const zend_string *key, char **val, int *vallen TSRMLS_DC
-#define PS_WRITE_ARGS void **mod_data, const zend_string *key, const char *val, const int vallen TSRMLS_DC
-#define PS_DESTROY_ARGS void **mod_data, const zend_string *key TSRMLS_DC
+#define PS_READ_ARGS void **mod_data, zend_string *key, zend_string **val TSRMLS_DC
+#define PS_WRITE_ARGS void **mod_data, zend_string *key, zend_string *val TSRMLS_DC
+#define PS_DESTROY_ARGS void **mod_data, zend_string *key TSRMLS_DC
 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
 #define PS_CREATE_SID_ARGS void **mod_data TSRMLS_DC
 
@@ -220,9 +220,9 @@ typedef struct ps_serializer_struct {
 
 PHPAPI void session_adapt_url(const char *, size_t, char **, size_t * TSRMLS_DC);
 
-PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC);
-PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC);
-PHPAPI zval *php_get_session_var(char *name, size_t namelen TSRMLS_DC);
+PHPAPI void php_add_session_var(zend_string *name TSRMLS_DC);
+PHPAPI void php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC);
+PHPAPI zval *php_get_session_var(zend_string *name TSRMLS_DC);
 
 PHPAPI int php_session_register_module(ps_module *);
 
@@ -239,39 +239,41 @@ PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC);
 PHPAPI int php_session_valid_key(const char *key);
 PHPAPI void php_session_reset_id(TSRMLS_D);
 
-#define PS_ADD_VARL(name,namelen) do {                                                                         \
-       php_add_session_var(name, namelen TSRMLS_CC);                                                   \
+#define PS_ADD_VARL(name) do {                                                                         \
+       php_add_session_var(name TSRMLS_CC);                                                    \
 } while (0)
 
-#define PS_ADD_VAR(name) PS_ADD_VARL(name, strlen(name))
+#define PS_ADD_VAR(name) PS_ADD_VARL(name)
 
-#define PS_DEL_VARL(name,namelen) do {                                                                         \
-       if (PS(http_session_vars)) {                                                                                    \
-               zend_hash_del(Z_ARRVAL_P(PS(http_session_vars)), name, namelen+1);      \
-       }                                                                                                                                               \
+#define PS_DEL_VARL(name) do {                                                                         \
+       if (!ZVAL_IS_NULL(&PS(http_session_vars))) {                                    \
+               zend_hash_del(Z_ARRVAL(PS(http_session_vars)), name);           \
+       }                                                                                                                               \
 } while (0)
 
 
-#define PS_ENCODE_VARS                                                                                         \
-       zend_string *key;                                                                                       \
-       ulong num_key;                                                                                          \
+#define PS_ENCODE_VARS                                                                                                 \
+       zend_string *key;                                                                                               \
+       ulong num_key;                                                                                                  \
        zval *struc;
 
-#define PS_ENCODE_LOOP(code) do {                                                                      \
-               HashTable *_ht = Z_ARRVAL(PS(http_session_vars));                       \
-               int key_type;                                                                                           \
-                                                                                                                                       \
-               for (zend_hash_internal_pointer_reset(_ht);                                     \
-                               (key_type = zend_hash_get_current_key_ex(_ht, &key, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTENT; \
-                                       zend_hash_move_forward(_ht)) {                                  \
-                       if (key_type == HASH_KEY_IS_LONG) {                                             \
-                               php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key);        \
-                               continue;                                                                                       \
-                       }                                                                                                               \
-                       if ((struc = php_get_session_var(key->val, key->len TSRMLS_CC))) {      \
-                               code;                                                                                           \
-                       }                                                                                                               \
-               }                                                                                                                       \
+#define PS_ENCODE_LOOP(code) do {                                                                              \
+               HashTable *_ht = Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars)));   \
+               int key_type;                                                                                                   \
+                                                                                                                                               \
+               for (zend_hash_internal_pointer_reset(_ht);                                             \
+                               (key_type = zend_hash_get_current_key_ex(_ht, &key,             \
+                                               &num_key, 0, NULL)) != HASH_KEY_NON_EXISTENT;   \
+                                       zend_hash_move_forward(_ht)) {                                          \
+                       if (key_type == HASH_KEY_IS_LONG) {                                                     \
+                               php_error_docref(NULL TSRMLS_CC, E_NOTICE,                              \
+                                               "Skipping numeric key %ld", num_key);                   \
+                               continue;                                                                                               \
+                       }                                                                                                                       \
+                       if ((struc = php_get_session_var(key TSRMLS_CC))) {                     \
+                               code;                                                                                                   \
+                       }                                                                                                                       \
+               }                                                                                                                               \
        } while(0)
 
 PHPAPI ZEND_EXTERN_MODULE_GLOBALS(ps)
index b62d388362c297f43d70002ff161982e70519caa..5cc1fa34644ab3d6164a9f4dd5decac4293bb1db 100644 (file)
@@ -78,7 +78,7 @@ zend_class_entry *php_session_id_iface_entry;
    *********** */
 
 #define IF_SESSION_VARS() \
-       if (Z_TYPE(PS(http_session_vars)) == IS_ARRAY)
+       if (Z_ISREF_P(&PS(http_session_vars)) && Z_TYPE_P(Z_REFVAL(PS(http_session_vars))) == IS_ARRAY)
 
 #define SESSION_CHECK_ACTIVE_STATE     \
        if (PS(session_status) == php_session_active) { \
@@ -140,12 +140,12 @@ static int php_session_destroy(TSRMLS_D) /* {{{ */
 }
 /* }}} */
 
-PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) /* {{{ */
+PHPAPI void php_add_session_var(zend_string *name TSRMLS_DC) /* {{{ */
 {
        zval *sym_track = NULL;
 
        IF_SESSION_VARS() {
-               sym_track = zend_hash_str_find(Z_ARRVAL(PS(http_session_vars)), name, namelen);
+               sym_track = zend_hash_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), name);
        } else {
                return;
        }
@@ -154,23 +154,23 @@ PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC) /* {{{ */
                zval empty_var;
 
                ZVAL_NULL(&empty_var);
-               ZEND_SET_SYMBOL_WITH_LENGTH(Z_ARRVAL(PS(http_session_vars)), name, namelen, &empty_var, 1, 0);
+               ZEND_SET_SYMBOL_WITH_LENGTH(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), name->val, name->len, &empty_var, 1, 0);
        }
 }
 /* }}} */
 
-PHPAPI void php_set_session_var(char *name, size_t namelen, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC) /* {{{ */
+PHPAPI void php_set_session_var(zend_string *name, zval *state_val, php_unserialize_data_t *var_hash TSRMLS_DC) /* {{{ */
 {
        IF_SESSION_VARS() {
-               zend_set_hash_symbol(state_val, name, namelen, Z_ISREF_P(state_val), 1, Z_ARRVAL(PS(http_session_vars)));
+               zend_set_hash_symbol(state_val, name->val, name->len, Z_ISREF_P(state_val), 1, Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))));
        }
 }
 /* }}} */
 
-PHPAPI zval* php_get_session_var(char *name, size_t namelen TSRMLS_DC) /* {{{ */
+PHPAPI zval* php_get_session_var(zend_string *name TSRMLS_DC) /* {{{ */
 {
        IF_SESSION_VARS() {
-               return zend_hash_str_find(Z_ARRVAL(PS(http_session_vars)), name, namelen);
+               return zend_hash_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), name);
        }
        return NULL;
 }
@@ -178,6 +178,7 @@ PHPAPI zval* php_get_session_var(char *name, size_t namelen TSRMLS_DC) /* {{{ */
 
 static void php_session_track_init(TSRMLS_D) /* {{{ */
 {
+       zval session_vars;
        zend_string *var_name = STR_INIT("_SESSION", sizeof("_SESSION") - 1, 0);
        /* Unconditionally destroy existing array -- possible dirty data */
        zend_delete_global_variable(var_name TSRMLS_CC);
@@ -187,7 +188,8 @@ static void php_session_track_init(TSRMLS_D) /* {{{ */
                zval_ptr_dtor(&PS(http_session_vars));
        }
 
-       array_init(&PS(http_session_vars));
+       array_init(&session_vars);
+       ZVAL_NEW_REF(&PS(http_session_vars), &session_vars);
 
        ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION") - 1, &PS(http_session_vars), 2, 1);
 }
@@ -455,8 +457,7 @@ PHPAPI int php_session_valid_key(const char *key) /* {{{ */
 
 static void php_session_initialize(TSRMLS_D) /* {{{ */
 {
-       char *val = NULL;
-       int vallen;
+       zend_string *val = NULL;
 
        if (!PS(mod)) {
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session");
@@ -489,7 +490,7 @@ static void php_session_initialize(TSRMLS_D) /* {{{ */
 
        /* Read data */
        php_session_track_init(TSRMLS_C);
-       if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == FAILURE) {
+       if (PS(mod)->s_read(&PS(mod_data), PS(id), &val TSRMLS_CC) == FAILURE) {
                /* Some broken save handler implementation returns FAILURE for non-existent session ID */
                /* It's better to raise error for this, but disabled error for better compatibility */
                /*
@@ -506,11 +507,11 @@ static void php_session_initialize(TSRMLS_D) /* {{{ */
 
                /* Store read data's MD5 hash */
                PHP_MD5Init(&context);
-               PHP_MD5Update(&context, val, vallen);
+               PHP_MD5Update(&context, val->val, val->len);
                PHP_MD5Final(PS(session_data_hash), &context);
 
-               php_session_decode(val, vallen TSRMLS_CC);
-               efree(val);
+               php_session_decode(val->val, val->len TSRMLS_CC);
+               STR_RELEASE(val);
        } else {
                memset(PS(session_data_hash),'\0', 16);
        }
@@ -543,13 +544,13 @@ static void php_session_save_current_state(TSRMLS_D) /* {{{ */
                                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->val, val->len TSRMLS_CC);
+                                       ret = PS(mod)->s_write(&PS(mod_data), PS(id), val TSRMLS_CC);
                                } else {
                                        ret = SUCCESS;
                                }
                                STR_RELEASE(val);
                        } else {
-                               ret = PS(mod)->s_write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC);
+                               ret = PS(mod)->s_write(&PS(mod_data), PS(id), STR_EMPTY_ALLOC() TSRMLS_CC);
                        }
                }
 
@@ -850,7 +851,7 @@ PS_SERIALIZER_ENCODE_FUNC(php_serialize) /* {{{ */
        php_serialize_data_t var_hash;
 
        PHP_VAR_SERIALIZE_INIT(var_hash);
-       php_var_serialize(&buf, &PS(http_session_vars), &var_hash TSRMLS_CC);
+       php_var_serialize(&buf, Z_REFVAL(PS(http_session_vars)), &var_hash TSRMLS_CC);
        PHP_VAR_SERIALIZE_DESTROY(var_hash);
        return buf.s;
 }
@@ -862,6 +863,7 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
        zval session_vars;
        php_unserialize_data_t var_hash;
 
+       ZVAL_NULL(&session_vars);
        PHP_VAR_UNSERIALIZE_INIT(var_hash);
        php_var_unserialize(&session_vars, &val, endptr, &var_hash TSRMLS_CC);
        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
@@ -869,10 +871,9 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
                zval_ptr_dtor(&PS(http_session_vars));
        }
        if (Z_TYPE(session_vars) == IS_NULL) {
-               array_init(&PS(http_session_vars));
-       } else {
-               ZVAL_COPY_VALUE(&PS(http_session_vars), &session_vars);
-       }
+               array_init(&session_vars);
+       } 
+       ZVAL_NEW_REF(&PS(http_session_vars), &session_vars);
        ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION") - 1, &PS(http_session_vars), 2, 1);
        return SUCCESS;
 }
@@ -911,11 +912,11 @@ PS_SERIALIZER_ENCODE_FUNC(php_binary) /* {{{ */
 PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
 {
        const char *p;
-       char *name;
        const char *endptr = val + vallen;
        zval current;
-       int namelen;
        int has_value;
+       int namelen;
+       zend_string *name;
        php_unserialize_data_t var_hash;
 
        PHP_VAR_UNSERIALIZE_INIT(var_hash);
@@ -930,11 +931,11 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
 
                has_value = *p & PS_BIN_UNDEF ? 0 : 1;
 
-               name = estrndup(p + 1, namelen);
+               name = STR_INIT(p + 1, namelen, 0);
 
                p += namelen + 1;
 
-               if ((tmp = zend_hash_str_find(&EG(symbol_table).ht, name, namelen))) {
+               if ((tmp = zend_hash_find(&EG(symbol_table).ht, name))) {
                        if ((Z_TYPE_P(tmp) == IS_ARRAY && Z_ARRVAL_P(tmp) == &EG(symbol_table).ht) || tmp == &PS(http_session_vars)) {
                                efree(name);
                                continue;
@@ -942,13 +943,14 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
                }
 
                if (has_value) {
+                       ZVAL_NULL(&current);
                        if (php_var_unserialize(&current, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
-                               php_set_session_var(name, namelen, &current, &var_hash  TSRMLS_CC);
+                               php_set_session_var(name, &current, &var_hash  TSRMLS_CC);
                        }
                        zval_ptr_dtor(&current);
                }
-               PS_ADD_VARL(name, namelen);
-               efree(name);
+               PS_ADD_VARL(name);
+               STR_RELEASE(name);
        }
 
        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
@@ -994,17 +996,18 @@ PS_SERIALIZER_ENCODE_FUNC(php) /* {{{ */
 PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
 {
        const char *p, *q;
-       char *name;
        const char *endptr = val + vallen;
-       zval current;
-       int namelen;
+       zval stack, *current = NULL;
        int has_value;
+       int namelen;
+       zend_string *name;
        php_unserialize_data_t var_hash;
 
        PHP_VAR_UNSERIALIZE_INIT(var_hash);
 
        p = val;
 
+       array_init(&stack);
        while (p < endptr) {
                zval *tmp;
                q = p;
@@ -1019,30 +1022,34 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
                }
 
                namelen = q - p;
-               name = estrndup(p, namelen);
+               name = STR_INIT(p, namelen, 0);
                q++;
 
-               if ((tmp = zend_hash_str_find(&EG(symbol_table).ht, name, namelen))) {
+               if ((tmp = zend_hash_find(&EG(symbol_table).ht, name))) {
                        if ((Z_TYPE_P(tmp) == IS_ARRAY && Z_ARRVAL_P(tmp) == &EG(symbol_table).ht) || tmp == &PS(http_session_vars)) {
                                goto skip;
                        }
                }
 
                if (has_value) {
-                       if (php_var_unserialize(&current, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
-                               php_set_session_var(name, namelen, &current, &var_hash  TSRMLS_CC);
+                       zval dummy;
+                       ZVAL_NULL(&dummy);
+                       //??? hash table resize?
+                       current = zend_hash_next_index_insert(Z_ARRVAL(stack), &dummy);
+                       if (php_var_unserialize(current, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) {
+                               php_set_session_var(name, current, &var_hash TSRMLS_CC);
                        }
-                       zval_ptr_dtor(&current);
                }
-               PS_ADD_VARL(name, namelen);
+               PS_ADD_VARL(name);
 skip:
-               efree(name);
+               STR_RELEASE(name);
 
                p = q;
        }
 break_outer_loop:
 
        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+       zval_ptr_dtor(&stack);
 
        return SUCCESS;
 }
@@ -1340,7 +1347,8 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */
 
        /*      'replace' must be 0 here, else a previous Set-Cookie
                header, probably sent with setcookie() will be replaced! */
-       sapi_add_header_ex(ncookie.s->val, ncookie.s->len, 0, 0 TSRMLS_CC);
+       sapi_add_header_ex(estrndup(ncookie.s->val, ncookie.s->len), ncookie.s->len, 0, 0 TSRMLS_CC);
+       smart_str_free(&ncookie);
 }
 /* }}} */
 
@@ -1404,6 +1412,7 @@ PHPAPI void php_session_reset_id(TSRMLS_D) /* {{{ */
                smart_str_appends(&var, PS(id)->val);
                smart_str_0(&var);
                REGISTER_STRINGL_CONSTANT("SID", var.s->val, var.s->len, 0);
+               smart_str_free(&var);
        } else {
                REGISTER_STRINGL_CONSTANT("SID", "", 0, 0);
        }
@@ -2101,7 +2110,7 @@ static PHP_FUNCTION(session_unset)
                HashTable *ht_sess_var;
 
                SEPARATE_ZVAL_IF_NOT_REF(&PS(http_session_vars));
-               ht_sess_var = Z_ARRVAL(PS(http_session_vars));
+               ht_sess_var = Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars)));
 
                /* Clean $_SESSION. */
                zend_hash_clean(ht_sess_var);
@@ -2459,9 +2468,7 @@ static PHP_MINIT_FUNCTION(session) /* {{{ */
 {
        zend_class_entry ce;
 
-       zend_string *sess_var = STR_INIT("_SESSION", sizeof("_SESSION") - 1, 0);
-       zend_register_auto_global(sess_var, 0, NULL TSRMLS_CC);
-       STR_RELEASE(sess_var);
+       zend_register_auto_global(STR_INIT("_SESSION", sizeof("_SESSION") - 1, 1), 0, NULL TSRMLS_CC);
 
        PS(module_number) = module_number; /* if we really need this var we need to init it in zts mode as well! */
 
@@ -2617,7 +2624,7 @@ static zend_bool php_check_cancel_upload(php_session_rfc1867_progress *progress
 {
        zval *progress_ary, *cancel_upload;
 
-       if ((progress_ary = zend_symtable_find(Z_ARRVAL(PS(http_session_vars)), progress->key.s)) == NULL) {
+       if ((progress_ary = zend_symtable_find(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), progress->key.s)) == NULL) {
                return 0;
        }
        if (Z_TYPE_P(progress_ary) != IS_ARRAY) {
@@ -2654,7 +2661,7 @@ static void php_session_rfc1867_update(php_session_rfc1867_progress *progress, i
        PS(session_status) = php_session_active;
        IF_SESSION_VARS() {
                progress->cancel_upload |= php_check_cancel_upload(progress TSRMLS_CC);
-               ZEND_SET_SYMBOL_WITH_LENGTH(Z_ARRVAL(PS(http_session_vars)), progress->key.s->val, progress->key.s->len, &progress->data, 2, 0);
+               ZEND_SET_SYMBOL_WITH_LENGTH(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), progress->key.s->val, progress->key.s->len, &progress->data, 2, 0);
        }
        php_session_flush(TSRMLS_C);
 } /* }}} */
@@ -2664,7 +2671,7 @@ static void php_session_rfc1867_cleanup(php_session_rfc1867_progress *progress T
        php_session_initialize(TSRMLS_C);
        PS(session_status) = php_session_active;
        IF_SESSION_VARS() {
-               zend_hash_del(Z_ARRVAL(PS(http_session_vars)), progress->key.s);
+               zend_hash_del(Z_ARRVAL_P(Z_REFVAL(PS(http_session_vars))), progress->key.s);
        }
        php_session_flush(TSRMLS_C);
 } /* }}} */
@@ -2806,6 +2813,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
                        if (data->temp_filename) {
                                add_assoc_string_ex(&progress->current_file, "tmp_name",  sizeof("tmp_name") - 1, data->temp_filename, 1);
                        }
+
                        add_assoc_long_ex(&progress->current_file, "error", sizeof("error") - 1, data->cancel_upload);
                        add_assoc_bool_ex(&progress->current_file, "done", sizeof("done") - 1,  1);
 
index 516befd21edd14b4c59985d80a04eedcec8a7749..35f10bf4f5e93bb1fd8b1c801b972f9c34cd9b43 100644 (file)
@@ -282,7 +282,7 @@ static void handle_form(STD_PARA)
                                if (!strncasecmp(ctx->tag.s->val, "form", sizeof("form") - 1)) {
                                        doit = 1;               
                                }
-                               if (doit && ctx->val.s->val && ctx->lookup_data && *ctx->lookup_data) {
+                               if (doit && ctx->val.s && ctx->lookup_data && *ctx->lookup_data) {
                                        char *e, *p = (char *)zend_memnstr(ctx->val.s->val, "://", sizeof("://") - 1, ctx->val.s->val + ctx->val.s->len);
                                        if (p) {
                                                e = memchr(p, '/', (ctx->val.s->val + ctx->val.s->len) - p);
@@ -1066,8 +1066,12 @@ PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int va
 
 PHPAPI int php_url_scanner_reset_vars(TSRMLS_D)
 {
-       BG(url_adapt_state_ex).form_app.s->len = 0;
-       BG(url_adapt_state_ex).url_app.s->len = 0;
+       if (BG(url_adapt_state_ex).form_app.s) {
+               BG(url_adapt_state_ex).form_app.s->len = 0;
+       }
+       if (BG(url_adapt_state_ex).url_app.s) {
+               BG(url_adapt_state_ex).url_app.s->len = 0;
+       }
 
        return SUCCESS;
 }
index 437fd1423d1fe219d9548af63f485f448214f2c8..2ad7191c8668df3ac949e12f7bab8b89b355ddf0 100644 (file)
@@ -518,8 +518,12 @@ PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int va
 
 PHPAPI int php_url_scanner_reset_vars(TSRMLS_D)
 {
-       BG(url_adapt_state_ex).form_app.s->len = 0;
-       BG(url_adapt_state_ex).url_app.s->len = 0;
+       if (BG(url_adapt_state_ex).form_app.s) {
+               BG(url_adapt_state_ex).form_app.s->len = 0;
+       }
+       if (BG(url_adapt_state_ex).url_app.s) {
+               BG(url_adapt_state_ex).url_app.s->len = 0;
+       }
 
        return SUCCESS;
 }