Skip to content

Commit

Permalink
BC fix for PR 109 merge - create_sid() method in SessionHandler
Browse files Browse the repository at this point in the history
Creates a new SessionIdInterface and moves create_sid() into it, so existing
handlers implementing SessionHandlerInterface don't require create_sid().
SessionHandler still includes the method so the default mod can be called, but
now implements both interfaces.

Also added several more tests for this feature.
  • Loading branch information
arraypad committed Jun 27, 2013
1 parent b66c14b commit 1e836cd
Show file tree
Hide file tree
Showing 9 changed files with 480 additions and 16 deletions.
3 changes: 3 additions & 0 deletions ext/session/php_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ extern zend_class_entry *php_session_class_entry;
#define PS_IFACE_NAME "SessionHandlerInterface"
extern zend_class_entry *php_session_iface_entry;

#define PS_SID_IFACE_NAME "SessionIdInterface"
extern zend_class_entry *php_session_id_iface_entry;

extern PHP_METHOD(SessionHandler, open);
extern PHP_METHOD(SessionHandler, close);
extern PHP_METHOD(SessionHandler, read);
Expand Down
53 changes: 45 additions & 8 deletions ext/session/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ zend_class_entry *php_session_class_entry;
/* SessionHandlerInterface */
zend_class_entry *php_session_iface_entry;

/* SessionIdInterface */
zend_class_entry *php_session_id_iface_entry;

/* ***********
* Helpers *
*********** */
Expand Down Expand Up @@ -1603,11 +1606,11 @@ static PHP_FUNCTION(session_set_save_handler)
RETURN_FALSE;
}

/* Find implemented methods */
zend_hash_internal_pointer_reset_ex(&php_session_class_entry->function_table, &pos);
/* Find implemented methods - SessionHandlerInterface */
zend_hash_internal_pointer_reset_ex(&php_session_iface_entry->function_table, &pos);
i = 0;
while (zend_hash_get_current_data_ex(&php_session_class_entry->function_table, (void **) &default_mptr, &pos) == SUCCESS) {
zend_hash_get_current_key_ex(&php_session_class_entry->function_table, &func_name, &func_name_len, &func_index, 0, &pos);
while (zend_hash_get_current_data_ex(&php_session_iface_entry->function_table, (void **) &default_mptr, &pos) == SUCCESS) {
zend_hash_get_current_key_ex(&php_session_iface_entry->function_table, &func_name, &func_name_len, &func_index, 0, &pos);

if (zend_hash_find(&Z_OBJCE_P(obj)->function_table, func_name, func_name_len, (void **)&current_mptr) == SUCCESS) {
if (PS(mod_user_names).names[i] != NULL) {
Expand All @@ -1625,7 +1628,29 @@ static PHP_FUNCTION(session_set_save_handler)
RETURN_FALSE;
}

zend_hash_move_forward_ex(&php_session_class_entry->function_table, &pos);
zend_hash_move_forward_ex(&php_session_iface_entry->function_table, &pos);
++i;
}

/* Find implemented methods - SessionIdInterface (optional) */
zend_hash_internal_pointer_reset_ex(&php_session_id_iface_entry->function_table, &pos);
while (zend_hash_get_current_data_ex(&php_session_id_iface_entry->function_table, (void **) &default_mptr, &pos) == SUCCESS) {
zend_hash_get_current_key_ex(&php_session_id_iface_entry->function_table, &func_name, &func_name_len, &func_index, 0, &pos);

if (zend_hash_find(&Z_OBJCE_P(obj)->function_table, func_name, func_name_len, (void **)&current_mptr) == SUCCESS) {
if (PS(mod_user_names).names[i] != NULL) {
zval_ptr_dtor(&PS(mod_user_names).names[i]);
}

MAKE_STD_ZVAL(callback);
array_init_size(callback, 2);
Z_ADDREF_P(obj);
add_next_index_zval(callback, obj);
add_next_index_stringl(callback, func_name, func_name_len - 1, 1);
PS(mod_user_names).names[i] = callback;
}

zend_hash_move_forward_ex(&php_session_id_iface_entry->function_table, &pos);
++i;
}

Expand Down Expand Up @@ -1993,7 +2018,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_session_void, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_session_set_save_handler, 0, 0, 7)
ZEND_BEGIN_ARG_INFO_EX(arginfo_session_set_save_handler, 0, 0, 1)
ZEND_ARG_INFO(0, open)
ZEND_ARG_INFO(0, close)
ZEND_ARG_INFO(0, read)
Expand Down Expand Up @@ -2083,7 +2108,14 @@ static const zend_function_entry php_session_iface_functions[] = {
PHP_ABSTRACT_ME(SessionHandlerInterface, write, arginfo_session_class_write)
PHP_ABSTRACT_ME(SessionHandlerInterface, destroy, arginfo_session_class_destroy)
PHP_ABSTRACT_ME(SessionHandlerInterface, gc, arginfo_session_class_gc)
PHP_ABSTRACT_ME(SessionHandlerInterface, create_sid, arginfo_session_class_create_sid)
{ NULL, NULL, NULL }
};
/* }}} */

/* {{{ SessionIdInterface functions[]
*/
static const zend_function_entry php_session_id_iface_functions[] = {
PHP_ABSTRACT_ME(SessionIdInterface, create_sid, arginfo_session_class_create_sid)
{ NULL, NULL, NULL }
};
/* }}} */
Expand Down Expand Up @@ -2206,15 +2238,20 @@ static PHP_MINIT_FUNCTION(session) /* {{{ */
php_session_rfc1867_orig_callback = php_rfc1867_callback;
php_rfc1867_callback = php_session_rfc1867_callback;

/* Register interface */
/* Register interfaces */
INIT_CLASS_ENTRY(ce, PS_IFACE_NAME, php_session_iface_functions);
php_session_iface_entry = zend_register_internal_class(&ce TSRMLS_CC);
php_session_iface_entry->ce_flags |= ZEND_ACC_INTERFACE;

INIT_CLASS_ENTRY(ce, PS_SID_IFACE_NAME, php_session_id_iface_functions);
php_session_id_iface_entry = zend_register_internal_class(&ce TSRMLS_CC);
php_session_id_iface_entry->ce_flags |= ZEND_ACC_INTERFACE;

/* Register base class */
INIT_CLASS_ENTRY(ce, PS_CLASS_NAME, php_session_class_functions);
php_session_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
zend_class_implements(php_session_class_entry TSRMLS_CC, 1, php_session_iface_entry);
zend_class_implements(php_session_class_entry TSRMLS_CC, 1, php_session_id_iface_entry);

REGISTER_LONG_CONSTANT("PHP_SESSION_DISABLED", php_session_disabled, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_SESSION_NONE", php_session_none, CONST_CS | CONST_PERSISTENT);
Expand Down
4 changes: 0 additions & 4 deletions ext/session/tests/session_set_save_handler_class_002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ class MySession2 extends SessionHandler {
}
return true;
}

public function create_sid() {
return parent::create_sid();
}
}

$handler = new MySession2;
Expand Down
90 changes: 90 additions & 0 deletions ext/session/tests/session_set_save_handler_class_016.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
--TEST--
Test session_set_save_handler() function: class with create_sid
--INI--
session.save_handler=files
session.name=PHPSESSID
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
<?php

ob_start();

/*
* Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
* Description : Sets user-level session storage functions
* Source code : ext/session/session.c
*/

echo "*** Testing session_set_save_handler() function: class with create_sid ***\n";

class MySession2 extends SessionHandler {
public $path;

public function open($path, $name) {
if (!$path) {
$path = sys_get_temp_dir();
}
$this->path = $path . '/u_sess_' . $name;
return true;
}

public function close() {
return true;
}

public function read($id) {
return @file_get_contents($this->path . $id);
}

public function write($id, $data) {
return file_put_contents($this->path . $id, $data);
}

public function destroy($id) {
@unlink($this->path . $id);
}

public function gc($maxlifetime) {
foreach (glob($this->path . '*') as $filename) {
if (filemtime($filename) + $maxlifetime < time()) {
@unlink($filename);
}
}
return true;
}

public function create_sid() {
return parent::create_sid();
}
}

$handler = new MySession2;
session_set_save_handler($handler);
session_start();

$_SESSION['foo'] = "hello";

var_dump(session_id(), ini_get('session.save_handler'), $_SESSION);

session_write_close();
session_unset();

session_start();
var_dump($_SESSION);

session_write_close();
session_unset();

--EXPECTF--
*** Testing session_set_save_handler() function: class with create_sid ***
string(%d) "%s"
string(4) "user"
array(1) {
["foo"]=>
string(5) "hello"
}
array(1) {
["foo"]=>
string(5) "hello"
}
90 changes: 90 additions & 0 deletions ext/session/tests/session_set_save_handler_class_017.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
--TEST--
Test session_set_save_handler() function: class with create_sid
--INI--
session.save_handler=files
session.name=PHPSESSID
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
<?php

ob_start();

/*
* Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
* Description : Sets user-level session storage functions
* Source code : ext/session/session.c
*/

echo "*** Testing session_set_save_handler() function: class with create_sid ***\n";

class MySession2 extends SessionHandler {
public $path;

public function open($path, $name) {
if (!$path) {
$path = sys_get_temp_dir();
}
$this->path = $path . '/u_sess_' . $name;
return true;
}

public function close() {
return true;
}

public function read($id) {
return @file_get_contents($this->path . $id);
}

public function write($id, $data) {
return file_put_contents($this->path . $id, $data);
}

public function destroy($id) {
@unlink($this->path . $id);
}

public function gc($maxlifetime) {
foreach (glob($this->path . '*') as $filename) {
if (filemtime($filename) + $maxlifetime < time()) {
@unlink($filename);
}
}
return true;
}

public function create_sid() {
return 'my_sid';
}
}

$handler = new MySession2;
session_set_save_handler($handler);
session_start();

$_SESSION['foo'] = "hello";

var_dump(session_id(), ini_get('session.save_handler'), $_SESSION);

session_write_close();
session_unset();

session_start();
var_dump($_SESSION);

session_write_close();
session_unset();

--EXPECTF--
*** Testing session_set_save_handler() function: class with create_sid ***
string(%d) "my_sid"
string(4) "user"
array(1) {
["foo"]=>
string(5) "hello"
}
array(1) {
["foo"]=>
string(5) "hello"
}
4 changes: 0 additions & 4 deletions ext/session/tests/session_set_save_handler_iface_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ class MySession2 implements SessionHandlerInterface {
}
return true;
}

public function create_sid() {
return md5(mt_rand());
}
}

$handler = new MySession2;
Expand Down
Loading

0 comments on commit 1e836cd

Please sign in to comment.