gwynne Fri Mar 7 23:20:15 2008 UTC
Added files:
/php-src/ext/session/tests bug32330.phpt
Modified files:
/php-src/ext/session mod_user.c mod_user.h php_session.h session.c
Log:
Fix bug #32330 (session_destroy, "Failed to initialize storage module",
custom session handler)
http://cvs.php.net/viewvc.cgi/php-src/ext/session/mod_user.c?r1=1.34&r2=1.35&diff_format=u
Index: php-src/ext/session/mod_user.c
diff -u php-src/ext/session/mod_user.c:1.34 php-src/ext/session/mod_user.c:1.35
--- php-src/ext/session/mod_user.c:1.34 Mon Dec 31 07:12:14 2007
+++ php-src/ext/session/mod_user.c Fri Mar 7 23:20:15 2008
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: mod_user.c,v 1.34 2007/12/31 07:12:14 sebastian Exp $ */
+/* $Id: mod_user.c,v 1.35 2008/03/07 23:20:15 gwynne Exp $ */
#include "php.h"
#include "php_session.h"
@@ -65,13 +65,16 @@
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) { \
@@ -84,29 +87,32 @@
PS_OPEN_FUNC(user)
{
zval *args[2];
- STDVARS;
+ static char dummy = 0;
+ STDVARS1;
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);
+ 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;
http://cvs.php.net/viewvc.cgi/php-src/ext/session/mod_user.h?r1=1.17&r2=1.18&diff_format=u
Index: php-src/ext/session/mod_user.h
diff -u php-src/ext/session/mod_user.h:1.17 php-src/ext/session/mod_user.h:1.18
--- php-src/ext/session/mod_user.h:1.17 Mon Dec 31 07:12:14 2007
+++ php-src/ext/session/mod_user.h Fri Mar 7 23:20:15 2008
@@ -16,23 +16,11 @@
+----------------------------------------------------------------------+
*/
-/* $Id: mod_user.h,v 1.17 2007/12/31 07:12:14 sebastian Exp $ */
+/* $Id: mod_user.h,v 1.18 2008/03/07 23:20:15 gwynne Exp $ */
#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
http://cvs.php.net/viewvc.cgi/php-src/ext/session/php_session.h?r1=1.115&r2=1.116&diff_format=u
Index: php-src/ext/session/php_session.h
diff -u php-src/ext/session/php_session.h:1.115
php-src/ext/session/php_session.h:1.116
--- php-src/ext/session/php_session.h:1.115 Mon Dec 31 07:12:14 2007
+++ php-src/ext/session/php_session.h Fri Mar 7 23:20:15 2008
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: php_session.h,v 1.115 2007/12/31 07:12:14 sebastian Exp $ */
+/* $Id: php_session.h,v 1.116 2008/03/07 23:20:15 gwynne Exp $ */
#ifndef PHP_SESSION_H
#define PHP_SESSION_H
@@ -116,6 +116,17 @@
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;
const struct ps_serializer_struct *serializer;
zval *http_session_vars;
zend_bool auto_start;
http://cvs.php.net/viewvc.cgi/php-src/ext/session/session.c?r1=1.480&r2=1.481&diff_format=u
Index: php-src/ext/session/session.c
diff -u php-src/ext/session/session.c:1.480 php-src/ext/session/session.c:1.481
--- php-src/ext/session/session.c:1.480 Thu Feb 28 14:16:13 2008
+++ php-src/ext/session/session.c Fri Mar 7 23:20:15 2008
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: session.c,v 1.480 2008/02/28 14:16:13 felipe Exp $ */
+/* $Id: session.c,v 1.481 2008/03/07 23:20:15 gwynne Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -82,6 +82,7 @@
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;
}
@@ -92,6 +93,7 @@
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);
@@ -1476,7 +1478,6 @@
{
zval **args[6];
int i;
- ps_user *mdata;
zval name;
if (PS(session_status) != php_session_none) {
@@ -1499,14 +1500,13 @@
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_P(*args[i]);
- mdata->names[i] = *args[i];
+ PS(mod_user_names).names[i] = *args[i];
}
-
- PS(mod_data) = (void *) mdata;
RETURN_TRUE;
}
@@ -1830,8 +1830,16 @@
static 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;
}
@@ -1839,12 +1847,17 @@
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;
}
http://cvs.php.net/viewvc.cgi/php-src/ext/session/tests/bug32330.phpt?view=markup&rev=1.1
Index: php-src/ext/session/tests/bug32330.phpt
+++ php-src/ext/session/tests/bug32330.phpt
--TEST--
Bug #32330 (session_destroy, "Failed to initialize storage module", custom
session handler)
--SKIPIF--
<?php include('skipif.inc'); ?>
--INI--
session.use_trans_sid=0
session.use_cookies=1
session.name=sid
session.save_path=/
session.gc_probability=1
session.gc_divisor=1
--FILE--
<?php
error_reporting(E_ALL);
function sOpen($path, $name)
{
echo "open: path = {$path}, name = {$name}\n";
return TRUE;
}
function sClose()
{
echo "close\n";
return TRUE;
}
function sRead($id)
{
echo "read: id = {$id}\n";
return '';
}
function sWrite($id, $data)
{
echo "write: id = {$id}, data = {$data}\n";
return TRUE;
}
function sDestroy($id)
{
echo "destroy: id = {$id}\n";
return TRUE;
}
function sGC($maxlifetime)
{
echo "gc: maxlifetime = {$maxlifetime}\n";
return TRUE;
}
session_set_save_handler( 'sOpen', 'sClose', 'sRead', 'sWrite', 'sDestroy',
'sGC' );
// without output buffering, the debug messages will cause all manner of
warnings
ob_start();
session_start();
$_SESSION['A'] = 'B';
session_write_close();
session_start();
$_SESSION['C'] = 'D';
session_destroy();
session_start();
$_SESSION['E'] = 'F';
// Don't try to destroy this time!
?>
--EXPECTF--
open: path = /, name = sid
read: id = %s
gc: maxlifetime = %d
write: id = %s, data = A|S:1:"B";
close
open: path = /, name = sid
read: id = %s
gc: maxlifetime = %d
destroy: id = %s
close
open: path = /, name = sid
read: id = %s
gc: maxlifetime = %d
write: id = %s, data = E|S:1:"F";
close
--UEXPECTF--
open: path = /, name = sid
read: id = %s
gc: maxlifetime = %d
write: id = %s, data = A|U:1:"B";
close
open: path = /, name = sid
read: id = %s
gc: maxlifetime = %d
destroy: id = %s
close
open: path = /, name = sid
read: id = %s
gc: maxlifetime = %d
write: id = %s, data = E|U:1:"F";
close
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php