. Fixed Bug #65315 (session.hash_function silently fallback to default md5)
(Yasuo)
. Implemented Request #54649 (Create session_serializer_name()). (Yasuo)
+ . Implemented Request #17860 (Session write short circuit). (Yasuo)
- mysqlnd:
. Disabled flag for SP OUT variables for 5.5+ servers as they are not natively
double rfc1867_min_freq; /* session.upload_progress.min_freq */
zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
+ char session_data_hash[16]; /* binary MD5 hash length */
} php_ps_globals;
typedef php_ps_globals zend_ps_globals;
*/
}
if (val) {
+ PHP_MD5_CTX context;
+
+ /* Store read data's MD5 hash */
+ PHP_MD5Init(&context);
+ PHP_MD5Update(&context, val, vallen);
+ PHP_MD5Final(PS(session_data_hash), &context);
+
php_session_decode(val, vallen TSRMLS_CC);
efree(val);
+ } else {
+ memset(PS(session_data_hash),'\0', 16);
}
if (!PS(use_cookies) && PS(send_cookie)) {
val = php_session_encode(&vallen TSRMLS_CC);
if (val) {
- ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC);
+ PHP_MD5_CTX context;
+ unsigned char digest[16];
+ char md5_hash[33];
+
+ /* Generate data's MD5 hash */
+ PHP_MD5Init(&context);
+ PHP_MD5Update(&context, val, vallen);
+ 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, vallen TSRMLS_CC);
+ } else {
+ ret = SUCCESS;
+ }
efree(val);
} else {
ret = PS(mod)->s_write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC);
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
session_start();
var_dump($_SESSION);
+$_SESSION['Bar'] = 'Foo';
session_write_close();
ob_end_flush();
["Guff"]=>
int(1234567890)
}
-Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
+Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";]
Close [%s,PHPSESSID]
session_start();
+$_SESSION['bar'] = 'hello';
session_write_close();
session_unset();
}
int(4)
string(%d) "%s"
-array(1) {
+array(2) {
["foo"]=>
string(5) "hello"
+ ["bar"]=>
+ string(5) "hello"
}
string(3) "hai"
session_set_save_handler($handler);
session_start();
+$_SESSION['abc'] = 'xyz';
// implicit close (called by shutdown function)
echo "done\n";
ob_end_flush();
(#2) constructor called
(#1) destructor called
done
-(#2) writing %s = foo|s:3:"bar";
+(#2) writing %s = foo|s:3:"bar";abc|s:3:"xyz";
(#2) closing %s
(#2) destructor called
session_id($session_id);
session_set_save_handler($open_closure, $close_closure, $read_closure, $write_closure, $destroy_closure, $gc_closure);
session_start();
+$_SESSION['Bar'] = 'Foo';
var_dump($_SESSION);
session_write_close();
Starting session again..!
Open [%s,PHPSESSID]
Read [%s,%s]
-array(3) {
+array(4) {
["Blah"]=>
string(12) "Hello World!"
["Foo"]=>
bool(false)
["Guff"]=>
int(1234567890)
+ ["Bar"]=>
+ string(3) "Foo"
}
-Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
+Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";]
Close [%s,PHPSESSID]
--- /dev/null
+--TEST--
+Test session_set_save_handler() function : test write short circuit
+--INI--
+session.save_path=
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(callback $open, callback $close, callback $read, callback $write, callback $destroy, callback $gc)
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() : test write short circuit ***\n";
+
+require_once "save_handler.inc";
+$path = dirname(__FILE__);
+session_save_path($path);
+session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
+
+session_start();
+$session_id = session_id();
+$_SESSION["Blah"] = "Hello World!";
+$_SESSION["Foo"] = FALSE;
+$_SESSION["Guff"] = 1234567890;
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+var_dump($_SESSION);
+
+echo "Starting session again..!\n";
+session_id($session_id);
+session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
+session_start();
+var_dump($_SESSION);
+$_SESSION['Bar'] = 'Foo';
+session_write_close();
+
+echo "Starting session again..!\n";
+session_id($session_id);
+session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
+session_start();
+var_dump($_SESSION);
+// $_SESSION should be the same and should skip write()
+session_write_close();
+
+ob_end_flush();
+?>
+--EXPECTF--
+*** Testing session_set_save_handler() : test write short circuit ***
+
+Open [%s,PHPSESSID]
+Read [%s,%s]
+array(3) {
+ ["Blah"]=>
+ string(12) "Hello World!"
+ ["Foo"]=>
+ bool(false)
+ ["Guff"]=>
+ int(1234567890)
+}
+Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;]
+Close [%s,PHPSESSID]
+array(3) {
+ ["Blah"]=>
+ string(12) "Hello World!"
+ ["Foo"]=>
+ bool(false)
+ ["Guff"]=>
+ int(1234567890)
+}
+Starting session again..!
+Open [%s,PHPSESSID]
+Read [%s,%s]
+array(3) {
+ ["Blah"]=>
+ string(12) "Hello World!"
+ ["Foo"]=>
+ bool(false)
+ ["Guff"]=>
+ int(1234567890)
+}
+Write [%s,%s,Blah|s:12:"Hello World!";Foo|b:0;Guff|i:1234567890;Bar|s:3:"Foo";]
+Close [%s,PHPSESSID]
+Starting session again..!
+Open [%s,PHPSESSID]
+Read [%s,%s]
+array(4) {
+ ["Blah"]=>
+ string(12) "Hello World!"
+ ["Foo"]=>
+ bool(false)
+ ["Guff"]=>
+ int(1234567890)
+ ["Bar"]=>
+ string(3) "Foo"
+}
+Close [%s,PHPSESSID]
\ No newline at end of file