summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGwynne Raskind <gwynne@php.net>2008-03-07 23:20:32 +0000
committerGwynne Raskind <gwynne@php.net>2008-03-07 23:20:32 +0000
commit3e99d5cc5b1c3f47e3c65d39d73cdd1943d9782f (patch)
tree5cbee476f2e7bb40e76753bbfe48d559b61c4592
parent278b7f2bdd51122e32b519f6703fbf32e0635dd2 (diff)
downloadphp-git-3e99d5cc5b1c3f47e3c65d39d73cdd1943d9782f.tar.gz
MFH: fix bug #32330 (session_destroy, "Failed to initialize storage module", custom session handler)
-rw-r--r--ext/session/mod_user.c30
-rw-r--r--ext/session/mod_user.h12
-rw-r--r--ext/session/php_session.h11
-rw-r--r--ext/session/session.c25
4 files changed, 49 insertions, 29 deletions
diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c
index 78e494f965..861c34c214 100644
--- a/ext/session/mod_user.c
+++ b/ext/session/mod_user.c
@@ -70,14 +70,17 @@ static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
return retval;
}
-#define STDVARS \
+#define STDVARS1 \
zval *retval; \
- int ret = FAILURE; \
- ps_user *mdata = PS_GET_MOD_DATA(); \
+ int ret = FAILURE
+
+#define STDVARS \
+ STDVARS1; \
+ char *mdata = PS_GET_MOD_DATA(); \
if (!mdata) \
return FAILURE
-#define PSF(a) mdata->name.ps_##a
+#define PSF(a) PS(mod_user_names).name.ps_##a
#define FINISH \
if (retval) { \
@@ -90,27 +93,32 @@ static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
PS_OPEN_FUNC(user)
{
zval *args[2];
- STDVARS;
+ static char dummy = 0;
+ STDVARS1;
SESS_ZVAL_STRING(save_path, args[0]);
SESS_ZVAL_STRING(session_name, args[1]);
retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC);
+ if (retval) {
+ /* This is necessary to fool the session module. Yes, it's safe to
+ * use a static. Neither mod_user nor the session module itself will
+ * ever touch this pointer. It could be set to 0xDEADBEEF for all the
+ * difference it makes, but for the sake of paranoia it's set to some
+ * valid value.
+ */
+ PS_SET_MOD_DATA(&dummy);
+ }
FINISH;
}
PS_CLOSE_FUNC(user)
{
- int i;
- STDVARS;
+ STDVARS1;
retval = ps_call_handler(PSF(close), 0, NULL TSRMLS_CC);
- for (i = 0; i < 6; i++)
- zval_ptr_dtor(&mdata->names[i]);
- efree(mdata);
-
PS_SET_MOD_DATA(NULL);
FINISH;
diff --git a/ext/session/mod_user.h b/ext/session/mod_user.h
index c245ff9f26..628aa55b13 100644
--- a/ext/session/mod_user.h
+++ b/ext/session/mod_user.h
@@ -21,18 +21,6 @@
#ifndef MOD_USER_H
#define MOD_USER_H
-typedef union {
- zval *names[6];
- struct {
- zval *ps_open;
- zval *ps_close;
- zval *ps_read;
- zval *ps_write;
- zval *ps_destroy;
- zval *ps_gc;
- } name;
-} ps_user;
-
extern ps_module ps_mod_user;
#define ps_user_ptr &ps_mod_user
diff --git a/ext/session/php_session.h b/ext/session/php_session.h
index 8896f58eab..9ecef8b16b 100644
--- a/ext/session/php_session.h
+++ b/ext/session/php_session.h
@@ -112,6 +112,17 @@ typedef struct _php_ps_globals {
long gc_maxlifetime;
int module_number;
long cache_expire;
+ union {
+ zval *names[6];
+ struct {
+ zval *ps_open;
+ zval *ps_close;
+ zval *ps_read;
+ zval *ps_write;
+ zval *ps_destroy;
+ zval *ps_gc;
+ } name;
+ } mod_user_names;
zend_bool bug_compat; /* Whether to behave like PHP 4.2 and earlier */
zend_bool bug_compat_warn; /* Whether to warn about it */
const struct ps_serializer_struct *serializer;
diff --git a/ext/session/session.c b/ext/session/session.c
index 2724b36cfe..9727541a0f 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -1489,7 +1489,6 @@ PHP_FUNCTION(session_set_save_handler)
{
zval **args[6];
int i;
- ps_user *mdata;
char *name;
if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
@@ -1509,14 +1508,13 @@ PHP_FUNCTION(session_set_save_handler)
zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
- mdata = emalloc(sizeof(*mdata));
-
for (i = 0; i < 6; i++) {
+ if (PS(mod_user_names).names[i] != NULL) {
+ zval_ptr_dtor(&PS(mod_user_names).names[i]);
+ }
Z_ADDREF_PP(args[i]);
- mdata->names[i] = *args[i];
+ PS(mod_user_names).names[i] = *args[i];
}
-
- PS(mod_data) = (void *) mdata;
RETURN_TRUE;
}
@@ -1870,6 +1868,7 @@ static void php_rinit_session_globals(TSRMLS_D)
PS(id) = NULL;
PS(session_status) = php_session_none;
PS(mod_data) = NULL;
+ /* Do NOT init PS(mod_user_names) here! */
PS(http_session_vars) = NULL;
}
@@ -1879,6 +1878,7 @@ static void php_rshutdown_session_globals(TSRMLS_D)
zval_ptr_dtor(&PS(http_session_vars));
PS(http_session_vars) = NULL;
}
+ /* Do NOT destroy PS(mod_user_names) here! */
if (PS(mod_data)) {
zend_try {
PS(mod)->s_close(&PS(mod_data) TSRMLS_CC);
@@ -1935,8 +1935,16 @@ PHP_FUNCTION(session_write_close)
PHP_RSHUTDOWN_FUNCTION(session)
{
+ int i;
+
php_session_flush(TSRMLS_C);
php_rshutdown_session_globals(TSRMLS_C);
+ /* this should NOT be done in php_rshutdown_session_globals() */
+ for (i = 0; i < 6; i++) {
+ if (PS(mod_user_names).names[i] != NULL) {
+ zval_ptr_dtor(&PS(mod_user_names).names[i]);
+ }
+ }
return SUCCESS;
}
@@ -1944,12 +1952,17 @@ PHP_RSHUTDOWN_FUNCTION(session)
static PHP_GINIT_FUNCTION(ps)
{
+ int i;
+
ps_globals->save_path = NULL;
ps_globals->session_name = NULL;
ps_globals->id = NULL;
ps_globals->mod = NULL;
ps_globals->mod_data = NULL;
ps_globals->session_status = php_session_none;
+ for (i = 0; i < 6; i++) {
+ ps_globals->mod_user_names.names[i] = NULL;
+ }
ps_globals->http_session_vars = NULL;
}