From: Xinchen Hui Date: Fri, 28 Mar 2014 10:46:25 +0000 (+0800) Subject: Refactor session (incompleted) X-Git-Tag: POST_PHPNG_MERGE~412^2~208 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3647fc6fcc63262e0347ee78a37b2410bf6a7035;p=php Refactor session (incompleted) --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index bcca30e1a3..f923740fbd 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -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; diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 4d5a18b36b..ddfb62ab6c 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -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--)) { diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c index 5573d4cdfd..4e42a1ba14 100644 --- a/ext/session/mod_user.c +++ b/ext/session/mod_user.c @@ -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); } /* diff --git a/ext/session/mod_user_class.c b/ext/session/mod_user_class.c index b5b51da129..78b90f49fa 100644 --- a/ext/session/mod_user_class.c +++ b/ext/session/mod_user_class.c @@ -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); } /* }}} */ diff --git a/ext/session/php_session.h b/ext/session/php_session.h index 0f402080ca..b50a35a1c4 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -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) diff --git a/ext/session/session.c b/ext/session/session.c index b62d388362..5cc1fa3464 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -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(¤t); if (php_var_unserialize(¤t, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { - php_set_session_var(name, namelen, ¤t, &var_hash TSRMLS_CC); + php_set_session_var(name, ¤t, &var_hash TSRMLS_CC); } zval_ptr_dtor(¤t); } - 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(¤t, (const unsigned char **) &q, (const unsigned char *) endptr, &var_hash TSRMLS_CC)) { - php_set_session_var(name, namelen, ¤t, &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(¤t); } - 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); diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c index 516befd21e..35f10bf4f5 100644 --- a/ext/standard/url_scanner_ex.c +++ b/ext/standard/url_scanner_ex.c @@ -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; } diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index 437fd1423d..2ad7191c86 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -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; }