1999-12-12 14:22:55 +00:00
/*
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2009-03-10 23:40:06 +00:00
| PHP Version 6 |
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2010-01-03 09:23:27 +00:00
| Copyright ( c ) 1997 - 2010 The PHP Group |
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 13:10:10 +00:00
| This source file is subject to version 3.01 of the PHP license , |
1999-07-16 13:13:16 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
2006-01-01 13:10:10 +00:00
| http : //www.php.net/license/3_01.txt |
1999-07-16 13:13:16 +00:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-07-10 10:09:15 +00:00
| Authors : Sascha Schumann < sascha @ schumann . cx > |
2002-05-13 17:28:38 +00:00
| Andrei Zmievski < andrei @ php . net > |
1999-06-05 19:52:58 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2001-06-06 14:32:27 +00:00
/* $Id$ */
2001-05-24 10:07:29 +00:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
2000-02-11 13:41:30 +00:00
# include "php.h"
2000-02-11 15:59:30 +00:00
# ifdef PHP_WIN32
1999-06-06 19:53:59 +00:00
# include "win32/time.h"
2000-02-11 13:41:30 +00:00
# else
# include <sys/time.h>
1999-06-06 18:22:17 +00:00
# endif
1999-06-05 19:52:58 +00:00
1999-12-12 14:16:55 +00:00
# include <sys/stat.h>
1999-09-11 17:20:31 +00:00
# include <fcntl.h>
1999-06-05 19:52:58 +00:00
# include "php_ini.h"
# include "SAPI.h"
2008-09-11 11:51:07 +00:00
# include "rfc1867.h"
# include "php_variables.h"
1999-06-05 19:52:58 +00:00
# include "php_session.h"
1999-06-06 19:53:59 +00:00
# include "ext/standard/md5.h"
2003-01-12 13:07:14 +00:00
# include "ext/standard/sha1.h"
1999-12-04 19:19:57 +00:00
# include "ext/standard/php_var.h"
2008-12-11 01:20:58 +00:00
# include "ext/date/php_date.h"
1999-09-01 14:20:15 +00:00
# include "ext/standard/php_lcg.h"
2000-09-20 01:22:55 +00:00
# include "ext/standard/url_scanner_ex.h"
2008-08-06 00:36:14 +00:00
# include "ext/standard/php_rand.h" /* for RAND_MAX */
2000-04-06 21:07:44 +00:00
# include "ext/standard/info.h"
2001-03-13 16:53:34 +00:00
# include "ext/standard/php_smart_str.h"
2007-06-17 14:26:16 +00:00
# include "ext/standard/url.h"
2001-03-13 16:53:34 +00:00
2001-05-03 15:48:49 +00:00
# include "mod_files.h"
# include "mod_user.h"
2002-06-28 02:27:02 +00:00
# ifdef HAVE_LIBMM
# include "mod_mm.h"
# endif
2007-01-04 22:04:38 +00:00
PHPAPI ZEND_DECLARE_MODULE_GLOBALS ( ps ) ;
2008-09-11 11:51:07 +00:00
static int ( * php_session_rfc1867_orig_callback ) ( unsigned int event , void * event_data , void * * extra TSRMLS_DC ) ;
static int php_session_rfc1867_callback ( unsigned int event , void * event_data , void * * extra TSRMLS_DC ) ;
2007-01-04 22:04:38 +00:00
/* ***********
* Helpers *
* * * * * * * * * * * */
# define IF_SESSION_VARS() \
if ( PS ( http_session_vars ) & & PS ( http_session_vars ) - > type = = IS_ARRAY )
# define SESSION_CHECK_ACTIVE_STATE \
if ( PS ( session_status ) = = php_session_active ) { \
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " A session is active. You cannot change the session module's ini settings at this time " ) ; \
return FAILURE ; \
}
/* Dispatched by RINIT and by php_session_destroy */
2008-08-06 00:36:14 +00:00
static inline void php_rinit_session_globals ( TSRMLS_D ) /* { { { */
2007-01-04 22:04:38 +00:00
{
PS ( id ) = NULL ;
PS ( session_status ) = php_session_none ;
PS ( mod_data ) = NULL ;
2008-03-07 23:20:15 +00:00
/* Do NOT init PS(mod_user_names) here! */
2007-01-04 22:04:38 +00:00
PS ( http_session_vars ) = NULL ;
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
/* Dispatched by RSHUTDOWN and by php_session_destroy */
2008-08-06 00:36:14 +00:00
static inline void php_rshutdown_session_globals ( TSRMLS_D ) /* { { { */
2007-01-04 22:04:38 +00:00
{
if ( PS ( http_session_vars ) ) {
zval_ptr_dtor ( & PS ( http_session_vars ) ) ;
PS ( http_session_vars ) = NULL ;
}
2008-03-07 23:20:15 +00:00
/* Do NOT destroy PS(mod_user_names) here! */
2007-01-04 22:04:38 +00:00
if ( PS ( mod_data ) ) {
zend_try {
PS ( mod ) - > s_close ( & PS ( mod_data ) TSRMLS_CC ) ;
} zend_end_try ( ) ;
}
if ( PS ( id ) ) {
efree ( PS ( id ) ) ;
}
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2008-08-06 00:36:14 +00:00
static int php_session_destroy ( TSRMLS_D ) /* { { { */
2007-01-04 22:04:38 +00:00
{
int retval = SUCCESS ;
if ( PS ( session_status ) ! = php_session_active ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Trying to destroy uninitialized session " ) ;
return FAILURE ;
}
if ( PS ( mod ) - > s_destroy ( & PS ( mod_data ) , PS ( id ) TSRMLS_CC ) = = FAILURE ) {
retval = FAILURE ;
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Session object destruction failed " ) ;
}
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
php_rshutdown_session_globals ( TSRMLS_C ) ;
php_rinit_session_globals ( TSRMLS_C ) ;
return retval ;
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2008-08-06 00:36:14 +00:00
PHPAPI void php_add_session_var ( char * name , size_t namelen TSRMLS_DC ) /* { { { */
2007-01-04 22:04:38 +00:00
{
zval * * sym_track = NULL ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
IF_SESSION_VARS ( ) {
2009-05-18 16:09:51 +00:00
zend_rt_hash_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 , ( void * ) & sym_track ) ;
2007-01-04 22:04:38 +00:00
} else {
return ;
}
if ( sym_track = = NULL ) {
zval * empty_var ;
ALLOC_INIT_ZVAL ( empty_var ) ;
ZEND_SET_SYMBOL_WITH_LENGTH ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 , empty_var , 1 , 0 ) ;
}
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2007-01-05 02:07:59 +00:00
/* BC? */
2008-08-06 00:36:14 +00:00
PHPAPI void php_set_session_var ( char * name , size_t namelen , zval * state_val , php_unserialize_data_t * var_hash TSRMLS_DC ) /* { { { */
2007-01-04 22:04:38 +00:00
{
2007-01-05 02:07:59 +00:00
zend_utf8_hash_update ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 , & state_val , sizeof ( zval * ) , NULL ) ;
zval_add_ref ( & state_val ) ;
2007-01-04 22:04:38 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2008-08-06 00:36:14 +00:00
PHPAPI int php_get_session_var ( char * name , size_t namelen , zval * * * state_var TSRMLS_DC ) /* { { { */
2007-01-04 22:04:38 +00:00
{
int ret = FAILURE ;
IF_SESSION_VARS ( ) {
2009-05-18 16:09:51 +00:00
ret = zend_rt_hash_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 , ( void * * ) state_var ) ;
2007-01-04 22:04:38 +00:00
}
return ret ;
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2008-08-06 00:36:14 +00:00
static void php_session_track_init ( TSRMLS_D ) /* { { { */
2007-01-04 22:04:38 +00:00
{
zval * session_vars = NULL ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
/* Unconditionally destroy existing arrays -- possible dirty data */
zend_delete_global_variable ( " _SESSION " , sizeof ( " _SESSION " ) - 1 TSRMLS_CC ) ;
if ( PS ( http_session_vars ) ) {
zval_ptr_dtor ( & PS ( http_session_vars ) ) ;
}
MAKE_STD_ZVAL ( session_vars ) ;
array_init ( session_vars ) ;
PS ( http_session_vars ) = session_vars ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
ZEND_SET_GLOBAL_VAR_WITH_LENGTH ( " _SESSION " , sizeof ( " _SESSION " ) , PS ( http_session_vars ) , 2 , 1 ) ;
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2008-08-06 00:36:14 +00:00
static char * php_session_encode ( int * newlen TSRMLS_DC ) /* { { { */
2007-01-04 22:04:38 +00:00
{
char * ret = NULL ;
IF_SESSION_VARS ( ) {
if ( ! PS ( serializer ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unknown session.serialize_handler. Failed to encode session object " ) ;
ret = NULL ;
} else if ( PS ( serializer ) - > encode ( & ret , newlen TSRMLS_CC ) = = FAILURE ) {
ret = NULL ;
}
} else {
2009-05-18 16:09:51 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot encode non-existent session " ) ;
2007-01-04 22:04:38 +00:00
}
return ret ;
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2008-08-06 00:36:14 +00:00
static void php_session_decode ( const char * val , int vallen TSRMLS_DC ) /* { { { */
2007-01-04 22:04:38 +00:00
{
if ( ! PS ( serializer ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Unknown session.serialize_handler. Failed to decode session object " ) ;
return ;
}
if ( PS ( serializer ) - > decode ( val , vallen TSRMLS_CC ) = = FAILURE ) {
php_session_destroy ( TSRMLS_C ) ;
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Failed to decode session object. Session has been destroyed " ) ;
}
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
/*
* Note that we cannot use the BASE64 alphabet here , because
* it contains " / " and " + " : both are unacceptable for simple inclusion
* into URLs .
2001-06-06 14:32:27 +00:00
*/
2007-01-04 22:04:38 +00:00
static char hexconvtab [ ] = " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,- " ;
enum {
PS_HASH_FUNC_MD5 ,
2007-01-05 03:57:57 +00:00
PS_HASH_FUNC_SHA1 ,
PS_HASH_FUNC_OTHER
1999-06-05 19:52:58 +00:00
} ;
2007-01-04 22:04:38 +00:00
/* returns a pointer to the byte after the last valid character in out */
2008-08-06 00:36:14 +00:00
static char * bin_to_readable ( char * in , size_t inlen , char * out , char nbits ) /* { { { */
2007-01-04 22:04:38 +00:00
{
unsigned char * p , * q ;
unsigned short w ;
int mask ;
int have ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
p = ( unsigned char * ) in ;
q = ( unsigned char * ) in + inlen ;
w = 0 ;
have = 0 ;
mask = ( 1 < < nbits ) - 1 ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
while ( 1 ) {
if ( have < nbits ) {
if ( p < q ) {
w | = * p + + < < have ;
have + = 8 ;
} else {
/* consumed everything? */
if ( have = = 0 ) break ;
/* No? We need a final round */
have = nbits ;
}
}
/* consume nbits */
* out + + = hexconvtab [ w & mask ] ;
w > > = nbits ;
have - = nbits ;
}
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
* out = ' \0 ' ;
return out ;
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2007-01-05 03:57:57 +00:00
# define PS_ID_INITIAL_SIZE 100
2008-08-06 00:36:14 +00:00
PHPAPI char * php_session_create_id ( PS_CREATE_SID_ARGS ) /* { { { */
2007-01-04 22:04:38 +00:00
{
PHP_MD5_CTX md5_context ;
PHP_SHA1_CTX sha1_context ;
2007-05-02 10:30:24 +00:00
# if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
2007-01-05 03:57:57 +00:00
void * hash_context ;
# endif
unsigned char * digest ;
2007-01-04 22:04:38 +00:00
int digest_len ;
int j ;
2009-07-17 14:21:31 +00:00
char * buf , * outid ;
2007-01-04 22:04:38 +00:00
struct timeval tv ;
zval * * array ;
zval * * token ;
char * remote_addr = NULL ;
gettimeofday ( & tv , NULL ) ;
2008-08-06 00:36:14 +00:00
2009-05-18 16:09:51 +00:00
if ( zend_ascii_hash_find ( & EG ( symbol_table ) , " _SERVER " , sizeof ( " _SERVER " ) , ( void * * ) & array ) = = SUCCESS & &
2007-01-04 22:04:38 +00:00
Z_TYPE_PP ( array ) = = IS_ARRAY & &
2009-05-18 16:09:51 +00:00
zend_ascii_hash_find ( Z_ARRVAL_PP ( array ) , " REMOTE_ADDR " , sizeof ( " REMOTE_ADDR " ) , ( void * * ) & token ) = = SUCCESS
) {
2007-01-04 22:04:38 +00:00
remote_addr = Z_STRVAL_PP ( token ) ;
}
2008-08-06 00:36:14 +00:00
/* maximum 15+19+19+10 bytes */
2009-05-18 16:09:51 +00:00
spprintf ( & buf , 0 , " %.15s%ld%ld%0.8F " , remote_addr ? remote_addr : " " , tv . tv_sec , ( long int ) tv . tv_usec , php_combined_lcg ( TSRMLS_C ) * 10 ) ;
2007-01-04 22:04:38 +00:00
switch ( PS ( hash_func ) ) {
case PS_HASH_FUNC_MD5 :
PHP_MD5Init ( & md5_context ) ;
PHP_MD5Update ( & md5_context , ( unsigned char * ) buf , strlen ( buf ) ) ;
digest_len = 16 ;
break ;
case PS_HASH_FUNC_SHA1 :
PHP_SHA1Init ( & sha1_context ) ;
PHP_SHA1Update ( & sha1_context , ( unsigned char * ) buf , strlen ( buf ) ) ;
digest_len = 20 ;
break ;
2007-05-02 10:30:24 +00:00
# if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
2007-01-05 03:57:57 +00:00
case PS_HASH_FUNC_OTHER :
if ( ! PS ( hash_ops ) ) {
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Invalid session hash function " ) ;
efree ( buf ) ;
return NULL ;
}
hash_context = emalloc ( PS ( hash_ops ) - > context_size ) ;
PS ( hash_ops ) - > hash_init ( hash_context ) ;
PS ( hash_ops ) - > hash_update ( hash_context , ( unsigned char * ) buf , strlen ( buf ) ) ;
digest_len = PS ( hash_ops ) - > digest_size ;
break ;
# endif /* HAVE_HASH_EXT */
2007-01-04 22:04:38 +00:00
default :
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Invalid session hash function " ) ;
efree ( buf ) ;
return NULL ;
}
2009-07-17 14:21:31 +00:00
efree ( buf ) ;
2007-01-04 22:04:38 +00:00
if ( PS ( entropy_length ) > 0 ) {
int fd ;
fd = VCWD_OPEN ( PS ( entropy_file ) , O_RDONLY ) ;
if ( fd > = 0 ) {
unsigned char rbuf [ 2048 ] ;
int n ;
int to_read = PS ( entropy_length ) ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
while ( to_read > 0 ) {
n = read ( fd , rbuf , MIN ( to_read , sizeof ( rbuf ) ) ) ;
if ( n < = 0 ) break ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
switch ( PS ( hash_func ) ) {
case PS_HASH_FUNC_MD5 :
PHP_MD5Update ( & md5_context , rbuf , n ) ;
break ;
case PS_HASH_FUNC_SHA1 :
PHP_SHA1Update ( & sha1_context , rbuf , n ) ;
break ;
2007-05-02 10:30:24 +00:00
# if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
2007-01-05 03:57:57 +00:00
case PS_HASH_FUNC_OTHER :
PS ( hash_ops ) - > hash_update ( hash_context , rbuf , n ) ;
break ;
# endif /* HAVE_HASH_EXT */
2007-01-04 22:04:38 +00:00
}
to_read - = n ;
}
close ( fd ) ;
}
}
2007-01-05 03:57:57 +00:00
digest = emalloc ( digest_len + 1 ) ;
2007-01-04 22:04:38 +00:00
switch ( PS ( hash_func ) ) {
case PS_HASH_FUNC_MD5 :
PHP_MD5Final ( digest , & md5_context ) ;
break ;
case PS_HASH_FUNC_SHA1 :
PHP_SHA1Final ( digest , & sha1_context ) ;
break ;
2007-05-02 10:30:24 +00:00
# if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
2007-01-05 03:57:57 +00:00
case PS_HASH_FUNC_OTHER :
PS ( hash_ops ) - > hash_final ( digest , hash_context ) ;
efree ( hash_context ) ;
break ;
# endif /* HAVE_HASH_EXT */
2007-01-04 22:04:38 +00:00
}
2001-05-01 17:01:51 +00:00
2007-01-04 22:04:38 +00:00
if ( PS ( hash_bits_per_character ) < 4
| | PS ( hash_bits_per_character ) > 6 ) {
PS ( hash_bits_per_character ) = 4 ;
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " The ini setting hash_bits_per_character is out of range (should be 4, 5, or 6) - using 4 for now " ) ;
}
2007-01-05 03:57:57 +00:00
2009-07-17 14:21:31 +00:00
outid = emalloc ( ( digest_len + 2 ) * ( ( 8.0f / PS ( hash_bits_per_character ) ) + 0.5 ) ) ;
j = ( int ) ( bin_to_readable ( ( char * ) digest , digest_len , outid , PS ( hash_bits_per_character ) ) - outid ) ;
2007-01-05 03:57:57 +00:00
efree ( digest ) ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
if ( newlen ) {
* newlen = j ;
}
2009-07-17 14:21:31 +00:00
return outid ;
2007-01-04 22:04:38 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2008-08-06 00:36:14 +00:00
static void php_session_initialize ( TSRMLS_D ) /* { { { */
2007-01-04 22:04:38 +00:00
{
char * val ;
int vallen ;
/* check session name for invalid characters */
2007-06-16 07:47:46 +00:00
if ( PS ( id ) & & strpbrk ( PS ( id ) , " \r \n \t <>' \" \\ " ) ) {
2007-01-04 22:04:38 +00:00
efree ( PS ( id ) ) ;
PS ( id ) = NULL ;
}
if ( ! PS ( mod ) ) {
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " No storage module chosen - failed to initialize session " ) ;
return ;
}
/* Open session handler first */
if ( PS ( mod ) - > s_open ( & PS ( mod_data ) , PS ( save_path ) , PS ( session_name ) TSRMLS_CC ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Failed to initialize storage module: %s (path: %s) " , PS ( mod ) - > s_name , PS ( save_path ) ) ;
return ;
}
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
/* If there is no ID, use session module to create one */
if ( ! PS ( id ) ) {
new_session :
PS ( id ) = PS ( mod ) - > s_create_sid ( & PS ( mod_data ) , NULL TSRMLS_CC ) ;
if ( PS ( use_cookies ) ) {
PS ( send_cookie ) = 1 ;
}
}
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
/* Read data */
/* Question: if you create a SID here, should you also try to read data?
* I ' m not sure , but while not doing so will remove one session operation
* it could prove usefull for those sites which wish to have " default "
2009-05-18 16:09:51 +00:00
* session information . */
2007-01-04 22:04:38 +00:00
php_session_track_init ( TSRMLS_C ) ;
PS ( invalid_session_id ) = 0 ;
if ( PS ( mod ) - > s_read ( & PS ( mod_data ) , PS ( id ) , & val , & vallen TSRMLS_CC ) = = SUCCESS ) {
php_session_decode ( val , vallen TSRMLS_CC ) ;
efree ( val ) ;
} else if ( PS ( invalid_session_id ) ) { /* address instances where the session read fails due to an invalid id */
PS ( invalid_session_id ) = 0 ;
efree ( PS ( id ) ) ;
2007-03-19 08:24:17 +00:00
PS ( id ) = NULL ;
2007-01-04 22:04:38 +00:00
goto new_session ;
}
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
2008-08-06 00:36:14 +00:00
static void php_session_save_current_state ( TSRMLS_D ) /* { { { */
2007-01-04 22:04:38 +00:00
{
int ret = FAILURE ;
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
IF_SESSION_VARS ( ) {
if ( PS ( mod_data ) ) {
char * val ;
int vallen ;
val = php_session_encode ( & vallen TSRMLS_CC ) ;
if ( val ) {
ret = PS ( mod ) - > s_write ( & PS ( mod_data ) , PS ( id ) , val , vallen TSRMLS_CC ) ;
efree ( val ) ;
} else {
ret = PS ( mod ) - > s_write ( & PS ( mod_data ) , PS ( id ) , " " , 0 TSRMLS_CC ) ;
}
}
if ( ret = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Failed to write session data (%s). Please "
" verify that the current setting of session.save_path "
" is correct (%s) " ,
PS ( mod ) - > s_name ,
PS ( save_path ) ) ;
}
}
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
if ( PS ( mod_data ) ) {
PS ( mod ) - > s_close ( & PS ( mod_data ) TSRMLS_CC ) ;
}
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
/* *************************
* INI Settings / Handlers *
* * * * * * * * * * * * * * * * * * * * * * * * * */
2003-12-14 23:24:50 +00:00
2008-08-06 00:36:14 +00:00
static PHP_INI_MH ( OnUpdateSaveHandler ) /* { { { */
2000-05-26 13:02:11 +00:00
{
2006-08-30 15:42:40 +00:00
ps_module * tmp ;
2003-12-14 23:24:50 +00:00
SESSION_CHECK_ACTIVE_STATE ;
2006-08-30 15:42:40 +00:00
tmp = _php_find_ps_module ( new_value TSRMLS_CC ) ;
2002-05-12 12:51:42 +00:00
2006-08-30 15:42:40 +00:00
if ( PG ( modules_activated ) & & ! tmp ) {
2006-08-30 16:24:31 +00:00
int err_type ;
2007-01-04 22:04:38 +00:00
2006-08-30 16:24:31 +00:00
if ( stage = = ZEND_INI_STAGE_RUNTIME ) {
err_type = E_WARNING ;
} else {
err_type = E_ERROR ;
}
2007-01-04 22:04:38 +00:00
2008-08-06 05:34:55 +00:00
/* Do not output error when restoring ini options. */
if ( stage ! = ZEND_INI_STAGE_DEACTIVATE ) {
php_error_docref ( NULL TSRMLS_CC , err_type , " Cannot find save handler '%s' " , new_value ) ;
}
2005-09-15 16:19:48 +00:00
return FAILURE ;
2002-05-12 12:51:42 +00:00
}
2006-08-30 15:42:40 +00:00
PS ( mod ) = tmp ;
2003-08-26 02:03:41 +00:00
2002-05-09 20:02:47 +00:00
return SUCCESS ;
2000-05-26 13:02:11 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2000-05-26 13:02:11 +00:00
2008-08-06 00:36:14 +00:00
static PHP_INI_MH ( OnUpdateSerializer ) /* { { { */
2003-12-14 23:24:50 +00:00
{
2006-08-30 15:42:40 +00:00
const ps_serializer * tmp ;
2003-12-14 23:24:50 +00:00
SESSION_CHECK_ACTIVE_STATE ;
2006-08-30 15:42:40 +00:00
tmp = _php_find_ps_serializer ( new_value TSRMLS_CC ) ;
2002-05-12 12:51:42 +00:00
2006-08-30 15:42:40 +00:00
if ( PG ( modules_activated ) & & ! tmp ) {
2006-08-30 16:24:31 +00:00
int err_type ;
2008-08-06 04:24:55 +00:00
2006-08-30 16:24:31 +00:00
if ( stage = = ZEND_INI_STAGE_RUNTIME ) {
err_type = E_WARNING ;
} else {
err_type = E_ERROR ;
}
2008-08-06 00:36:14 +00:00
2008-08-06 05:34:55 +00:00
/* Do not output error when restoring ini options. */
if ( stage ! = ZEND_INI_STAGE_DEACTIVATE ) {
php_error_docref ( NULL TSRMLS_CC , err_type , " Cannot find serialization handler '%s' " , new_value ) ;
}
2005-09-15 16:19:48 +00:00
return FAILURE ;
2002-05-12 12:51:42 +00:00
}
2006-08-30 15:42:40 +00:00
PS ( serializer ) = tmp ;
2003-08-26 02:03:41 +00:00
2002-05-09 20:02:47 +00:00
return SUCCESS ;
2000-05-26 13:02:11 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2000-05-26 13:02:11 +00:00
2008-08-06 05:34:55 +00:00
static PHP_INI_MH ( OnUpdateTransSid ) /* { { { */
{
SESSION_CHECK_ACTIVE_STATE ;
if ( ! strncasecmp ( new_value , " on " , sizeof ( " on " ) ) ) {
PS ( use_trans_sid ) = ( zend_bool ) 1 ;
} else {
PS ( use_trans_sid ) = ( zend_bool ) atoi ( new_value ) ;
}
return SUCCESS ;
}
/* }}} */
2008-08-06 00:36:14 +00:00
static PHP_INI_MH ( OnUpdateSaveDir ) /* { { { */
2005-05-23 06:46:25 +00:00
{
2005-05-21 17:37:56 +00:00
/* Only do the safemode/open_basedir check at runtime */
2007-08-03 01:40:05 +00:00
if ( stage = = PHP_INI_STAGE_RUNTIME | | stage = = PHP_INI_STAGE_HTACCESS ) {
2008-08-06 04:24:55 +00:00
char * p ;
2006-10-01 21:00:00 +00:00
2006-12-01 00:27:33 +00:00
if ( memchr ( new_value , ' \0 ' , new_value_length ) ! = NULL ) {
return FAILURE ;
}
2010-01-31 18:06:29 +00:00
/* we do not use zend_memrchr() since path can contain ; itself */
if ( ( p = strchr ( new_value , ' ; ' ) ) ) {
char * p2 ;
2006-10-01 21:00:00 +00:00
p + + ;
2010-01-31 18:06:29 +00:00
if ( ( p2 = strchr ( p , ' ; ' ) ) ) {
p = p2 + 1 ;
}
2006-10-01 21:00:00 +00:00
} else {
p = new_value ;
}
2009-12-04 01:21:32 +00:00
if ( * p & & php_check_open_basedir ( p TSRMLS_CC ) ) {
2005-05-21 17:37:56 +00:00
return FAILURE ;
}
}
2007-01-04 22:04:38 +00:00
2005-05-21 17:37:56 +00:00
OnUpdateString ( entry , new_value , new_value_length , mh_arg1 , mh_arg2 , mh_arg3 , stage TSRMLS_CC ) ;
2005-05-22 12:57:26 +00:00
return SUCCESS ;
2005-05-21 17:37:56 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2000-05-26 13:02:11 +00:00
2008-08-06 00:36:14 +00:00
static PHP_INI_MH ( OnUpdateHashFunc ) /* { { { */
2007-01-05 03:57:57 +00:00
{
2008-08-06 00:36:14 +00:00
long val ;
2007-01-05 03:57:57 +00:00
char * endptr = NULL ;
2007-05-02 10:30:24 +00:00
# if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
2007-01-05 03:57:57 +00:00
PS ( hash_ops ) = NULL ;
# endif
val = strtol ( new_value , & endptr , 10 ) ;
if ( endptr & & ( * endptr = = ' \0 ' ) ) {
/* Numeric value */
PS ( hash_func ) = val ? 1 : 0 ;
return SUCCESS ;
}
if ( new_value_length = = ( sizeof ( " md5 " ) - 1 ) & &
strncasecmp ( new_value , " md5 " , sizeof ( " md5 " ) - 1 ) = = 0 ) {
PS ( hash_func ) = PS_HASH_FUNC_MD5 ;
return SUCCESS ;
}
if ( new_value_length = = ( sizeof ( " sha1 " ) - 1 ) & &
strncasecmp ( new_value , " sha1 " , sizeof ( " sha1 " ) - 1 ) = = 0 ) {
PS ( hash_func ) = PS_HASH_FUNC_SHA1 ;
return SUCCESS ;
}
2008-08-06 00:36:14 +00:00
# if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH) /* {{{ */
2007-01-05 03:57:57 +00:00
{
2007-09-27 18:28:44 +00:00
php_hash_ops * ops = ( php_hash_ops * ) php_hash_fetch_ops ( new_value , new_value_length ) ;
2007-01-05 03:57:57 +00:00
if ( ops ) {
PS ( hash_func ) = PS_HASH_FUNC_OTHER ;
PS ( hash_ops ) = ops ;
return SUCCESS ;
}
}
2008-09-11 11:51:07 +00:00
# endif /* HAVE_HASH_EXT }}} */
2007-01-05 03:57:57 +00:00
2008-08-06 00:36:14 +00:00
return FAILURE ;
2007-01-05 03:57:57 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-05 03:57:57 +00:00
2008-09-11 11:51:07 +00:00
static PHP_INI_MH ( OnUpdateRfc1867Freq ) /* { { { */
{
int tmp ;
tmp = zend_atoi ( new_value , new_value_length ) ;
if ( tmp < 0 ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " session.upload_progress.freq must be greater than or equal to zero " ) ;
return FAILURE ;
}
if ( new_value_length > 0 & & new_value [ new_value_length - 1 ] = = ' % ' ) {
if ( tmp > 100 ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " session.upload_progress.freq cannot be over 100%% " ) ;
return FAILURE ;
}
PS ( rfc1867_freq ) = - tmp ;
} else {
PS ( rfc1867_freq ) = tmp ;
}
return SUCCESS ;
} /* }}} */
2001-06-06 14:32:27 +00:00
/* {{{ PHP_INI
*/
2007-01-04 22:04:38 +00:00
PHP_INI_BEGIN ( )
STD_PHP_INI_ENTRY ( " session.save_path " , " " , PHP_INI_ALL , OnUpdateSaveDir , save_path , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.name " , " PHPSESSID " , PHP_INI_ALL , OnUpdateString , session_name , php_ps_globals , ps_globals )
PHP_INI_ENTRY ( " session.save_handler " , " files " , PHP_INI_ALL , OnUpdateSaveHandler )
STD_PHP_INI_BOOLEAN ( " session.auto_start " , " 0 " , PHP_INI_ALL , OnUpdateBool , auto_start , php_ps_globals , ps_globals )
2008-08-06 04:24:55 +00:00
STD_PHP_INI_ENTRY ( " session.gc_probability " , " 1 " , PHP_INI_ALL , OnUpdateLong , gc_probability , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.gc_divisor " , " 100 " , PHP_INI_ALL , OnUpdateLong , gc_divisor , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.gc_maxlifetime " , " 1440 " , PHP_INI_ALL , OnUpdateLong , gc_maxlifetime , php_ps_globals , ps_globals )
2007-01-04 22:04:38 +00:00
PHP_INI_ENTRY ( " session.serialize_handler " , " php " , PHP_INI_ALL , OnUpdateSerializer )
2008-08-06 04:24:55 +00:00
STD_PHP_INI_ENTRY ( " session.cookie_lifetime " , " 0 " , PHP_INI_ALL , OnUpdateLong , cookie_lifetime , php_ps_globals , ps_globals )
2007-01-04 22:04:38 +00:00
STD_PHP_INI_ENTRY ( " session.cookie_path " , " / " , PHP_INI_ALL , OnUpdateString , cookie_path , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.cookie_domain " , " " , PHP_INI_ALL , OnUpdateString , cookie_domain , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.cookie_secure " , " " , PHP_INI_ALL , OnUpdateBool , cookie_secure , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.cookie_httponly " , " " , PHP_INI_ALL , OnUpdateBool , cookie_httponly , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.use_cookies " , " 1 " , PHP_INI_ALL , OnUpdateBool , use_cookies , php_ps_globals , ps_globals )
STD_PHP_INI_BOOLEAN ( " session.use_only_cookies " , " 1 " , PHP_INI_ALL , OnUpdateBool , use_only_cookies , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.referer_check " , " " , PHP_INI_ALL , OnUpdateString , extern_referer_chk , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.entropy_file " , " " , PHP_INI_ALL , OnUpdateString , entropy_file , php_ps_globals , ps_globals )
2008-08-06 04:24:55 +00:00
STD_PHP_INI_ENTRY ( " session.entropy_length " , " 0 " , PHP_INI_ALL , OnUpdateLong , entropy_length , php_ps_globals , ps_globals )
2007-01-04 22:04:38 +00:00
STD_PHP_INI_ENTRY ( " session.cache_limiter " , " nocache " , PHP_INI_ALL , OnUpdateString , cache_limiter , php_ps_globals , ps_globals )
2008-08-06 04:24:55 +00:00
STD_PHP_INI_ENTRY ( " session.cache_expire " , " 180 " , PHP_INI_ALL , OnUpdateLong , cache_expire , php_ps_globals , ps_globals )
PHP_INI_ENTRY ( " session.use_trans_sid " , " 0 " , PHP_INI_ALL , OnUpdateTransSid )
PHP_INI_ENTRY ( " session.hash_function " , " 0 " , PHP_INI_ALL , OnUpdateHashFunc )
STD_PHP_INI_ENTRY ( " session.hash_bits_per_character " , " 4 " , PHP_INI_ALL , OnUpdateLong , hash_bits_per_character , php_ps_globals , ps_globals )
2002-10-03 04:53:05 +00:00
2008-09-11 11:51:07 +00:00
/* Upload progress */
2009-05-18 16:09:51 +00:00
STD_PHP_INI_BOOLEAN ( " session.upload_progress.enabled " , " 1 " , ZEND_INI_PERDIR , OnUpdateBool , rfc1867_enabled , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.upload_progress.prefix " , " upload_progress_ " , ZEND_INI_PERDIR , OnUpdateUTF8String , rfc1867_prefix , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.upload_progress.name " , " PHP_SESSION_UPLOAD_PROGRESS " , ZEND_INI_PERDIR , OnUpdateUTF8String , rfc1867_name , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.upload_progress.freq " , " 1% " , ZEND_INI_PERDIR , OnUpdateRfc1867Freq , rfc1867_freq , php_ps_globals , ps_globals )
STD_PHP_INI_ENTRY ( " session.upload_progress.min_freq " , " 0 " , ZEND_INI_PERDIR , OnUpdateReal , rfc1867_min_freq , php_ps_globals , ps_globals )
2008-09-11 11:51:07 +00:00
2007-01-04 22:04:38 +00:00
/* Commented out until future discussion */
/* PHP_INI_ENTRY("session.encode_sources", "globals,track", PHP_INI_ALL, NULL) */
PHP_INI_END ( )
/* }}} */
2002-10-03 04:53:05 +00:00
2007-01-04 22:04:38 +00:00
/* ***************
* Serializers *
* * * * * * * * * * * * * * * */
1999-11-29 23:07:20 +00:00
2000-09-01 15:24:58 +00:00
# define PS_BIN_NR_OF_BITS 8
# define PS_BIN_UNDEF (1<<(PS_BIN_NR_OF_BITS-1))
# define PS_BIN_MAX (PS_BIN_UNDEF-1)
2008-08-06 00:36:14 +00:00
PS_SERIALIZER_ENCODE_FUNC ( php_binary ) /* {{{ */
2000-09-01 15:24:58 +00:00
{
2002-05-09 20:02:47 +00:00
smart_str buf = { 0 } ;
php_serialize_data_t var_hash ;
PS_ENCODE_VARS ;
PHP_VAR_SERIALIZE_INIT ( var_hash ) ;
2007-01-05 02:07:59 +00:00
PS_UENCODE_LOOP (
2008-08-06 04:24:55 +00:00
if ( key_length > PS_BIN_MAX | | key_type ! = HASH_KEY_IS_STRING ) continue ;
if ( struc ) {
smart_str_appendc ( & buf , ( unsigned char ) key_length ) ;
smart_str_appendl ( & buf , key . s , key_length ) ;
php_var_serialize ( & buf , struc , & var_hash TSRMLS_CC ) ;
} else {
smart_str_appendc ( & buf , ( unsigned char ) key_length | PS_BIN_UNDEF ) ;
smart_str_appendl ( & buf , key . s , key_length ) ;
}
2002-05-09 20:02:47 +00:00
) ;
2008-08-06 00:36:14 +00:00
2007-01-05 02:07:59 +00:00
if ( newlen ) {
* newlen = buf . len ;
}
smart_str_0 ( & buf ) ;
2002-05-09 20:02:47 +00:00
* newstr = buf . c ;
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
2002-05-09 19:42:00 +00:00
2002-05-09 20:02:47 +00:00
return SUCCESS ;
2000-09-01 15:24:58 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2000-09-01 15:24:58 +00:00
2008-08-06 00:36:14 +00:00
PS_SERIALIZER_DECODE_FUNC ( php_binary ) /* {{{ */
2000-09-01 15:24:58 +00:00
{
2002-05-09 20:02:47 +00:00
const char * p ;
char * name ;
const char * endptr = val + vallen ;
zval * current ;
int namelen ;
int has_value ;
php_unserialize_data_t var_hash ;
PHP_VAR_UNSERIALIZE_INIT ( var_hash ) ;
for ( p = val ; p < endptr ; ) {
2006-12-26 17:18:28 +00:00
zval * * tmp ;
2007-01-05 02:07:59 +00:00
namelen = ( ( unsigned char ) ( * p ) ) & ( ~ PS_BIN_UNDEF ) ;
2006-12-31 22:26:06 +00:00
2008-08-06 04:24:55 +00:00
if ( namelen < 0 | | namelen > PS_BIN_MAX | | ( p + namelen ) > = endptr ) {
2006-12-31 22:26:06 +00:00
return FAILURE ;
}
2002-05-09 20:02:47 +00:00
has_value = * p & PS_BIN_UNDEF ? 0 : 1 ;
name = estrndup ( p + 1 , namelen ) ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
p + = namelen + 1 ;
2006-12-26 17:18:28 +00:00
if ( zend_hash_find ( & EG ( symbol_table ) , name , namelen + 1 , ( void * * ) & tmp ) = = SUCCESS ) {
if ( ( Z_TYPE_PP ( tmp ) = = IS_ARRAY & & Z_ARRVAL_PP ( tmp ) = = & EG ( symbol_table ) ) | | * tmp = = PS ( http_session_vars ) ) {
efree ( name ) ;
continue ;
2008-08-06 04:24:55 +00:00
}
}
2006-12-26 17:18:28 +00:00
2002-05-09 20:02:47 +00:00
if ( has_value ) {
2005-01-21 16:03:47 +00:00
ALLOC_INIT_ZVAL ( current ) ;
2006-07-13 00:13:42 +00:00
if ( php_var_unserialize ( & current , ( const unsigned char * * ) & p , ( const unsigned char * ) endptr , & var_hash TSRMLS_CC ) ) {
2007-01-05 02:07:59 +00:00
zend_utf8_hash_update ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 , & current , sizeof ( zval * ) , NULL ) ;
} else {
zval_ptr_dtor ( & current ) ;
2002-05-09 20:02:47 +00:00
}
}
PS_ADD_VARL ( name , namelen ) ;
efree ( name ) ;
}
PHP_VAR_UNSERIALIZE_DESTROY ( var_hash ) ;
return SUCCESS ;
2000-09-01 15:24:58 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2000-09-01 15:24:58 +00:00
# define PS_DELIMITER '|'
# define PS_UNDEF_MARKER '!'
2008-08-06 00:36:14 +00:00
PS_SERIALIZER_ENCODE_FUNC ( php ) /* {{{ */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
smart_str buf = { 0 } ;
php_serialize_data_t var_hash ;
PS_ENCODE_VARS ;
PHP_VAR_SERIALIZE_INIT ( var_hash ) ;
2007-01-05 02:07:59 +00:00
PS_UENCODE_LOOP (
if ( ! struc ) {
smart_str_appendc ( & buf , PS_UNDEF_MARKER ) ;
}
if ( key_type = = HASH_KEY_IS_STRING ) {
2006-02-21 20:12:43 +00:00
if ( memchr ( key . s , PS_DELIMITER , key_length ) ) {
2004-09-02 02:44:04 +00:00
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
2008-08-06 00:36:14 +00:00
smart_str_free ( & buf ) ;
2004-09-02 02:44:04 +00:00
return FAILURE ;
}
2007-04-04 19:46:42 +00:00
smart_str_appendl ( & buf , key . s , key_length ) ;
2007-01-05 02:07:59 +00:00
} else {
/* HASH_KEY_IS_UNICODE */
char * str = NULL ;
int len ;
UErrorCode status = U_ZERO_ERROR ;
zend_unicode_to_string_ex ( UG ( utf8_conv ) , & str , & len , key . u , key_length , & status ) ;
if ( U_FAILURE ( status ) | | memchr ( str , PS_DELIMITER , key_length ) ) {
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
smart_str_free ( & buf ) ;
if ( str ) { efree ( str ) ; }
return FAILURE ;
}
smart_str_appendl ( & buf , str , len ) ;
efree ( str ) ;
}
smart_str_appendc ( & buf , PS_DELIMITER ) ;
if ( struc ) {
2002-05-09 20:02:47 +00:00
php_var_serialize ( & buf , struc , & var_hash TSRMLS_CC ) ;
2007-01-05 02:07:59 +00:00
}
2002-05-09 20:02:47 +00:00
) ;
2008-08-06 00:36:14 +00:00
2008-08-06 04:24:55 +00:00
if ( newlen ) {
* newlen = buf . len ;
}
2007-01-05 02:07:59 +00:00
smart_str_0 ( & buf ) ;
2002-05-09 20:02:47 +00:00
* newstr = buf . c ;
PHP_VAR_SERIALIZE_DESTROY ( var_hash ) ;
return SUCCESS ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 00:36:14 +00:00
PS_SERIALIZER_DECODE_FUNC ( php ) /* {{{ */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
const char * p , * q ;
char * name ;
const char * endptr = val + vallen ;
zval * current ;
int namelen ;
int has_value ;
php_unserialize_data_t var_hash ;
PHP_VAR_UNSERIALIZE_INIT ( var_hash ) ;
p = val ;
while ( p < endptr ) {
2006-12-26 17:18:28 +00:00
zval * * tmp ;
2007-01-05 02:07:59 +00:00
has_value = 1 ;
2002-05-09 20:02:47 +00:00
q = p ;
2007-01-04 22:04:38 +00:00
while ( * q ! = PS_DELIMITER ) {
2002-05-09 20:02:47 +00:00
if ( + + q > = endptr ) goto break_outer_loop ;
2007-01-04 22:04:38 +00:00
}
2008-08-06 00:36:14 +00:00
2007-01-05 02:07:59 +00:00
if ( * p = = PS_UNDEF_MARKER ) {
if ( + + p > = endptr ) goto break_outer_loop ;
2002-05-09 20:02:47 +00:00
has_value = 0 ;
}
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
namelen = q - p ;
name = estrndup ( p , namelen ) ;
q + + ;
2006-12-26 17:18:28 +00:00
if ( zend_hash_find ( & EG ( symbol_table ) , name , namelen + 1 , ( void * * ) & tmp ) = = SUCCESS ) {
if ( ( Z_TYPE_PP ( tmp ) = = IS_ARRAY & & Z_ARRVAL_PP ( tmp ) = = & EG ( symbol_table ) ) | | * tmp = = PS ( http_session_vars ) ) {
goto skip ;
2008-08-06 04:24:55 +00:00
}
}
2006-12-26 17:18:28 +00:00
2002-05-09 20:02:47 +00:00
if ( has_value ) {
2004-02-29 00:26:36 +00:00
ALLOC_INIT_ZVAL ( current ) ;
2006-07-13 00:13:42 +00:00
if ( php_var_unserialize ( & current , ( const unsigned char * * ) & q , ( const unsigned char * ) endptr , & var_hash TSRMLS_CC ) ) {
2007-01-05 02:07:59 +00:00
zend_utf8_hash_update ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , name , namelen + 1 , & current , sizeof ( zval * ) , NULL ) ;
} else {
zval_ptr_dtor ( & current ) ;
2002-05-09 20:02:47 +00:00
}
}
PS_ADD_VARL ( name , namelen ) ;
2006-12-26 17:18:28 +00:00
skip :
2002-05-09 20:02:47 +00:00
efree ( name ) ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
p = q ;
}
2001-07-25 19:02:13 +00:00
break_outer_loop :
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
PHP_VAR_UNSERIALIZE_DESTROY ( var_hash ) ;
2001-06-21 18:46:26 +00:00
2002-05-09 20:02:47 +00:00
return SUCCESS ;
1999-07-01 05:45:48 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-07-01 05:45:48 +00:00
2007-01-04 22:04:38 +00:00
# define MAX_SERIALIZERS 10
# define PREDEFINED_SERIALIZERS 2
2003-01-12 13:07:14 +00:00
2007-01-04 22:04:38 +00:00
static ps_serializer ps_serializers [ MAX_SERIALIZERS + 1 ] = {
PS_SERIALIZER_ENTRY ( php ) ,
PS_SERIALIZER_ENTRY ( php_binary )
2003-01-12 13:07:14 +00:00
} ;
2001-05-19 09:58:31 +00:00
2009-05-18 16:09:51 +00:00
PHPAPI int php_session_register_serializer ( const char * name , int ( * encode ) ( PS_SERIALIZER_ENCODE_ARGS ) , int ( * decode ) ( PS_SERIALIZER_DECODE_ARGS ) ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2007-01-04 22:04:38 +00:00
int ret = - 1 ;
int i ;
2002-09-29 18:33:14 +00:00
2007-01-04 22:04:38 +00:00
for ( i = 0 ; i < MAX_SERIALIZERS ; i + + ) {
if ( ps_serializers [ i ] . name = = NULL ) {
ps_serializers [ i ] . name = name ;
ps_serializers [ i ] . encode = encode ;
ps_serializers [ i ] . decode = decode ;
ps_serializers [ i + 1 ] . name = NULL ;
ret = 0 ;
break ;
}
2002-05-09 20:02:47 +00:00
}
2007-01-04 22:04:38 +00:00
return ret ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2008-08-06 04:24:55 +00:00
2007-01-04 22:04:38 +00:00
/* *******************
* Storage Modules *
* * * * * * * * * * * * * * * * * * * */
2002-05-09 20:02:47 +00:00
2007-01-04 22:04:38 +00:00
# define MAX_MODULES 10
# define PREDEFINED_MODULES 2
2002-10-03 03:23:02 +00:00
2007-01-04 22:04:38 +00:00
static ps_module * ps_modules [ MAX_MODULES + 1 ] = {
ps_files_ptr ,
ps_user_ptr
} ;
2002-10-03 05:53:45 +00:00
2008-08-06 00:36:14 +00:00
PHPAPI int php_session_register_module ( ps_module * ptr ) /* { { { */
2007-01-04 22:04:38 +00:00
{
int ret = - 1 ;
int i ;
for ( i = 0 ; i < MAX_MODULES ; i + + ) {
if ( ! ps_modules [ i ] ) {
ps_modules [ i ] = ptr ;
ret = 0 ;
break ;
2008-08-06 00:36:14 +00:00
}
2002-05-09 20:02:47 +00:00
}
2007-01-04 22:04:38 +00:00
return ret ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-04 22:04:38 +00:00
/* ******************
* Cache Limiters *
* * * * * * * * * * * * * * * * * * */
typedef struct {
char * name ;
void ( * func ) ( TSRMLS_D ) ;
} php_session_cache_limiter_t ;
# define CACHE_LIMITER(name) _php_cache_limiter_##name
# define CACHE_LIMITER_FUNC(name) static void CACHE_LIMITER(name)(TSRMLS_D)
# define CACHE_LIMITER_ENTRY(name) { #name, CACHE_LIMITER(name) },
# define ADD_HEADER(a) sapi_add_header(a, strlen(a), 1);
# define MAX_STR 512
1999-12-12 14:16:55 +00:00
static char * month_names [ ] = {
2002-05-09 20:02:47 +00:00
" Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " ,
" Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec "
1999-12-12 14:16:55 +00:00
} ;
1999-12-12 14:22:55 +00:00
static char * week_days [ ] = {
2002-05-09 20:02:47 +00:00
" Sun " , " Mon " , " Tue " , " Wed " , " Thu " , " Fri " , " Sat " , " Sun "
1999-12-12 14:16:55 +00:00
} ;
2008-08-06 00:36:14 +00:00
static inline void strcpy_gmt ( char * ubuf , time_t * when ) /* { { { */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
char buf [ MAX_STR ] ;
2007-06-07 08:58:38 +00:00
struct tm tm , * res ;
2002-05-09 20:02:47 +00:00
int n ;
2008-08-06 00:36:14 +00:00
2007-06-07 08:58:38 +00:00
res = php_gmtime_r ( when , & tm ) ;
2008-08-06 00:36:14 +00:00
2007-06-07 08:58:38 +00:00
if ( ! res ) {
buf [ 0 ] = ' \0 ' ;
return ;
}
2008-08-06 04:24:55 +00:00
n = slprintf ( buf , sizeof ( buf ) , " %s, %02d %s %d %02d:%02d:%02d GMT " , /* SAFE */
2009-05-18 16:09:51 +00:00
week_days [ tm . tm_wday ] , tm . tm_mday ,
month_names [ tm . tm_mon ] , tm . tm_year + 1900 ,
tm . tm_hour , tm . tm_min ,
2002-05-09 20:02:47 +00:00
tm . tm_sec ) ;
memcpy ( ubuf , buf , n ) ;
ubuf [ n ] = ' \0 ' ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-12-12 14:16:55 +00:00
2008-08-06 00:36:14 +00:00
static inline void last_modified ( TSRMLS_D ) /* { { { */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
const char * path ;
struct stat sb ;
char buf [ MAX_STR + 1 ] ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
path = SG ( request_info ) . path_translated ;
if ( path ) {
if ( VCWD_STAT ( path , & sb ) = = - 1 ) {
return ;
}
1999-12-12 14:16:55 +00:00
2001-03-13 16:53:34 +00:00
# define LAST_MODIFIED "Last-Modified: "
2002-05-09 20:02:47 +00:00
memcpy ( buf , LAST_MODIFIED , sizeof ( LAST_MODIFIED ) - 1 ) ;
2009-11-03 21:21:34 +00:00
strcpy_gmt ( buf + sizeof ( LAST_MODIFIED ) - 1 , & sb . st_mtime ) ;
2003-04-27 16:04:53 +00:00
ADD_HEADER ( buf ) ;
2002-05-09 20:02:47 +00:00
}
1999-12-12 14:16:55 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-12-12 14:16:55 +00:00
2007-01-04 22:04:38 +00:00
# define EXPIRES "Expires: "
2008-08-06 00:36:14 +00:00
CACHE_LIMITER_FUNC ( public ) /* {{{ */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
char buf [ MAX_STR + 1 ] ;
struct timeval tv ;
time_t now ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
gettimeofday ( & tv , NULL ) ;
now = tv . tv_sec + PS ( cache_expire ) * 60 ;
memcpy ( buf , EXPIRES , sizeof ( EXPIRES ) - 1 ) ;
strcpy_gmt ( buf + sizeof ( EXPIRES ) - 1 , & now ) ;
2003-04-27 16:04:53 +00:00
ADD_HEADER ( buf ) ;
2008-08-06 00:36:14 +00:00
2007-02-24 16:25:58 +00:00
snprintf ( buf , sizeof ( buf ) , " Cache-Control: public, max-age=%ld " , PS ( cache_expire ) * 60 ) ; /* SAFE */
2003-04-27 16:04:53 +00:00
ADD_HEADER ( buf ) ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
last_modified ( TSRMLS_C ) ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2001-09-21 13:38:44 +00:00
2008-08-06 00:36:14 +00:00
CACHE_LIMITER_FUNC ( private_no_expire ) /* {{{ */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
char buf [ MAX_STR + 1 ] ;
2008-08-06 00:36:14 +00:00
2007-02-24 16:25:58 +00:00
snprintf ( buf , sizeof ( buf ) , " Cache-Control: private, max-age=%ld, pre-check=%ld " , PS ( cache_expire ) * 60 , PS ( cache_expire ) * 60 ) ; /* SAFE */
2003-04-27 16:04:53 +00:00
ADD_HEADER ( buf ) ;
1999-12-12 14:16:55 +00:00
2002-05-09 20:02:47 +00:00
last_modified ( TSRMLS_C ) ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-12-12 14:16:55 +00:00
2008-08-06 00:36:14 +00:00
CACHE_LIMITER_FUNC ( private ) /* {{{ */
2001-11-02 22:27:07 +00:00
{
2003-04-27 16:04:53 +00:00
ADD_HEADER ( " Expires: Thu, 19 Nov 1981 08:52:00 GMT " ) ;
2002-05-12 12:51:42 +00:00
CACHE_LIMITER ( private_no_expire ) ( TSRMLS_C ) ;
2001-11-02 22:27:07 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2001-11-02 22:27:07 +00:00
2008-08-06 00:36:14 +00:00
CACHE_LIMITER_FUNC ( nocache ) /* {{{ */
1999-12-12 14:16:55 +00:00
{
2003-04-27 16:04:53 +00:00
ADD_HEADER ( " Expires: Thu, 19 Nov 1981 08:52:00 GMT " ) ;
2007-01-04 22:04:38 +00:00
2002-05-09 20:02:47 +00:00
/* For HTTP/1.1 conforming clients and the rest (MSIE 5) */
2003-04-27 16:04:53 +00:00
ADD_HEADER ( " Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 " ) ;
2007-01-04 22:04:38 +00:00
2002-05-09 20:02:47 +00:00
/* For HTTP/1.0 conforming clients */
2003-04-27 16:04:53 +00:00
ADD_HEADER ( " Pragma: no-cache " ) ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-12-12 14:16:55 +00:00
2000-09-06 14:16:12 +00:00
static php_session_cache_limiter_t php_session_cache_limiters [ ] = {
2002-05-12 12:51:42 +00:00
CACHE_LIMITER_ENTRY ( public )
CACHE_LIMITER_ENTRY ( private )
CACHE_LIMITER_ENTRY ( private_no_expire )
CACHE_LIMITER_ENTRY ( nocache )
2002-05-09 20:02:47 +00:00
{ 0 }
1999-12-12 14:16:55 +00:00
} ;
2008-08-06 00:36:14 +00:00
static int php_session_cache_limiter ( TSRMLS_D ) /* { { { */
1999-12-12 14:16:55 +00:00
{
2002-05-09 20:02:47 +00:00
php_session_cache_limiter_t * lim ;
2002-10-03 15:10:36 +00:00
if ( PS ( cache_limiter ) [ 0 ] = = ' \0 ' ) return 0 ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
if ( SG ( headers_sent ) ) {
2006-06-03 11:19:44 +00:00
char * output_start_filename = php_output_get_start_filename ( TSRMLS_C ) ;
int output_start_lineno = php_output_get_start_lineno ( TSRMLS_C ) ;
2002-05-09 20:02:47 +00:00
if ( output_start_filename ) {
2009-05-18 16:09:51 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cache limiter - headers already sent (output started at %s:%d) " , output_start_filename , output_start_lineno ) ;
2002-05-09 20:02:47 +00:00
} else {
2002-12-05 20:13:35 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cache limiter - headers already sent " ) ;
2008-08-06 00:36:14 +00:00
}
2002-10-03 15:10:36 +00:00
return - 2 ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
for ( lim = php_session_cache_limiters ; lim - > name ; lim + + ) {
if ( ! strcasecmp ( lim - > name , PS ( cache_limiter ) ) ) {
lim - > func ( TSRMLS_C ) ;
2002-10-03 15:10:36 +00:00
return 0 ;
2002-05-09 20:02:47 +00:00
}
}
2002-10-03 15:10:36 +00:00
return - 1 ;
1999-12-12 14:16:55 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2007-01-04 22:04:38 +00:00
/* *********************
* Cookie Management *
* * * * * * * * * * * * * * * * * * * * * */
2001-03-13 16:53:34 +00:00
# define COOKIE_SET_COOKIE "Set-Cookie: "
2002-05-09 20:02:47 +00:00
# define COOKIE_EXPIRES "; expires="
# define COOKIE_PATH "; path="
# define COOKIE_DOMAIN "; domain="
# define COOKIE_SECURE "; secure"
2006-08-10 13:56:54 +00:00
# define COOKIE_HTTPONLY "; HttpOnly"
1999-06-05 19:52:58 +00:00
2008-08-06 00:36:14 +00:00
static void php_session_send_cookie ( TSRMLS_D ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
smart_str ncookie = { 0 } ;
char * date_fmt = NULL ;
2007-06-16 07:47:46 +00:00
char * e_session_name , * e_id ;
2002-05-09 20:02:47 +00:00
if ( SG ( headers_sent ) ) {
2006-06-03 11:19:44 +00:00
char * output_start_filename = php_output_get_start_filename ( TSRMLS_C ) ;
int output_start_lineno = php_output_get_start_lineno ( TSRMLS_C ) ;
2002-05-09 20:02:47 +00:00
if ( output_start_filename ) {
2009-05-18 16:09:51 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cookie - headers already sent by (output started at %s:%d) " , output_start_filename , output_start_lineno ) ;
2002-05-09 20:02:47 +00:00
} else {
2002-12-05 20:13:35 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot send session cookie - headers already sent " ) ;
2008-08-06 00:36:14 +00:00
}
2002-05-09 20:02:47 +00:00
return ;
}
2008-08-06 00:36:14 +00:00
2007-06-16 07:47:46 +00:00
/* URL encode session_name and id because they might be user supplied */
e_session_name = php_url_encode ( PS ( session_name ) , strlen ( PS ( session_name ) ) , NULL ) ;
e_id = php_url_encode ( PS ( id ) , strlen ( PS ( id ) ) , NULL ) ;
2002-05-09 20:02:47 +00:00
smart_str_appends ( & ncookie , COOKIE_SET_COOKIE ) ;
2007-06-16 07:47:46 +00:00
smart_str_appends ( & ncookie , e_session_name ) ;
2002-05-09 20:02:47 +00:00
smart_str_appendc ( & ncookie , ' = ' ) ;
2007-06-16 07:47:46 +00:00
smart_str_appends ( & ncookie , e_id ) ;
2008-08-06 00:36:14 +00:00
2007-06-16 07:47:46 +00:00
efree ( e_session_name ) ;
efree ( e_id ) ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
if ( PS ( cookie_lifetime ) > 0 ) {
struct timeval tv ;
2003-10-08 10:22:51 +00:00
time_t t ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
gettimeofday ( & tv , NULL ) ;
2003-10-08 10:22:51 +00:00
t = tv . tv_sec + PS ( cookie_lifetime ) ;
2008-08-06 00:36:14 +00:00
2003-10-08 10:22:51 +00:00
if ( t > 0 ) {
2008-12-11 01:20:58 +00:00
date_fmt = php_format_date ( " D, d-M-Y H:i:s T " , sizeof ( " D, d-M-Y H:i:s T " ) - 1 , t , 0 TSRMLS_CC ) ;
2003-10-08 10:22:51 +00:00
smart_str_appends ( & ncookie , COOKIE_EXPIRES ) ;
smart_str_appends ( & ncookie , date_fmt ) ;
efree ( date_fmt ) ;
}
2002-05-09 20:02:47 +00:00
}
if ( PS ( cookie_path ) [ 0 ] ) {
smart_str_appends ( & ncookie , COOKIE_PATH ) ;
smart_str_appends ( & ncookie , PS ( cookie_path ) ) ;
}
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
if ( PS ( cookie_domain ) [ 0 ] ) {
smart_str_appends ( & ncookie , COOKIE_DOMAIN ) ;
smart_str_appends ( & ncookie , PS ( cookie_domain ) ) ;
}
if ( PS ( cookie_secure ) ) {
smart_str_appends ( & ncookie , COOKIE_SECURE ) ;
}
2006-08-10 13:56:54 +00:00
if ( PS ( cookie_httponly ) ) {
smart_str_appends ( & ncookie , COOKIE_HTTPONLY ) ;
}
2002-05-09 20:02:47 +00:00
smart_str_0 ( & ncookie ) ;
2008-08-06 00:36:14 +00:00
2006-07-12 15:28:18 +00:00
/* 'replace' must be 0 here, else a previous Set-Cookie
header , probably sent with setcookie ( ) will be replaced ! */
2003-04-27 16:18:43 +00:00
sapi_add_header_ex ( ncookie . c , ncookie . len , 0 , 0 TSRMLS_CC ) ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 00:36:14 +00:00
PHPAPI ps_module * _php_find_ps_module ( char * name TSRMLS_DC ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
ps_module * ret = NULL ;
ps_module * * mod ;
int i ;
2007-01-04 22:04:38 +00:00
for ( i = 0 , mod = ps_modules ; i < MAX_MODULES ; i + + , mod + + ) {
2003-02-11 00:42:14 +00:00
if ( * mod & & ! strcasecmp ( name , ( * mod ) - > s_name ) ) {
2002-05-09 20:02:47 +00:00
ret = * mod ;
break ;
}
2007-01-04 22:04:38 +00:00
}
2002-05-09 20:02:47 +00:00
return ret ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 00:36:14 +00:00
PHPAPI const ps_serializer * _php_find_ps_serializer ( char * name TSRMLS_DC ) /* { { { */
1999-07-01 05:45:48 +00:00
{
2002-05-09 20:02:47 +00:00
const ps_serializer * ret = NULL ;
const ps_serializer * mod ;
1999-07-01 05:45:48 +00:00
2007-01-04 22:04:38 +00:00
for ( mod = ps_serializers ; mod - > name ; mod + + ) {
2002-05-09 20:02:47 +00:00
if ( ! strcasecmp ( name , mod - > name ) ) {
ret = mod ;
break ;
}
2007-01-04 22:04:38 +00:00
}
2002-05-09 20:02:47 +00:00
return ret ;
1999-07-01 05:45:48 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-07-01 05:45:48 +00:00
1999-12-22 00:38:04 +00:00
# define PPID2SID \
2002-05-09 20:02:47 +00:00
convert_to_string ( ( * ppid ) ) ; \
PS ( id ) = estrndup ( Z_STRVAL_PP ( ppid ) , Z_STRLEN_PP ( ppid ) )
1999-12-22 00:38:04 +00:00
2008-08-06 00:36:14 +00:00
static void php_session_reset_id ( TSRMLS_D ) /* { { { */
2003-02-18 19:29:38 +00:00
{
int module_number = PS ( module_number ) ;
2008-08-06 00:36:14 +00:00
2006-02-10 07:41:59 +00:00
if ( PS ( use_cookies ) & & PS ( send_cookie ) ) {
2003-02-18 19:29:38 +00:00
php_session_send_cookie ( TSRMLS_C ) ;
2008-08-06 00:36:14 +00:00
PS ( send_cookie ) = 0 ;
2003-02-18 19:29:38 +00:00
}
/* if the SID constant exists, destroy it. */
2006-09-19 10:38:31 +00:00
zend_ascii_hash_del ( EG ( zend_constants ) , " sid " , sizeof ( " sid " ) ) ;
2008-08-06 00:36:14 +00:00
2003-02-18 19:29:38 +00:00
if ( PS ( define_sid ) ) {
smart_str var = { 0 } ;
smart_str_appends ( & var , PS ( session_name ) ) ;
smart_str_appendc ( & var , ' = ' ) ;
smart_str_appends ( & var , PS ( id ) ) ;
smart_str_0 ( & var ) ;
REGISTER_STRINGL_CONSTANT ( " SID " , var . c , var . len , 0 ) ;
} else {
2005-06-01 18:27:50 +00:00
REGISTER_STRINGL_CONSTANT ( " SID " , STR_EMPTY_ALLOC ( ) , 0 , 0 ) ;
2003-02-18 19:29:38 +00:00
}
if ( PS ( apply_trans_sid ) ) {
php_url_scanner_reset_vars ( TSRMLS_C ) ;
2003-02-20 06:18:16 +00:00
php_url_scanner_add_var ( PS ( session_name ) , strlen ( PS ( session_name ) ) , PS ( id ) , strlen ( PS ( id ) ) , 1 TSRMLS_CC ) ;
2003-02-18 19:29:38 +00:00
}
}
2008-08-06 00:36:14 +00:00
/* }}} */
PHPAPI void php_session_start ( TSRMLS_D ) /* { { { */
1999-06-05 22:15:49 +00:00
{
2002-05-09 20:02:47 +00:00
zval * * ppid ;
zval * * data ;
2008-08-06 05:34:55 +00:00
char * p , * value ;
2002-05-09 20:02:47 +00:00
int nrand ;
int lensess ;
PS ( apply_trans_sid ) = PS ( use_trans_sid ) ;
2008-08-06 05:34:55 +00:00
switch ( PS ( session_status ) ) {
case php_session_active :
php_error ( E_NOTICE , " A session had already been started - ignoring session_start() " ) ;
return ;
break ;
2004-09-30 12:19:59 +00:00
2008-08-06 05:34:55 +00:00
case php_session_disabled :
2004-09-30 12:19:59 +00:00
value = zend_ini_string ( " session.save_handler " , sizeof ( " session.save_handler " ) , 0 ) ;
2008-08-06 05:34:55 +00:00
if ( ! PS ( mod ) & & value ) {
PS ( mod ) = _php_find_ps_module ( value TSRMLS_CC ) ;
if ( ! PS ( mod ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot find save handler '%s' - session startup failed " , value ) ;
return ;
}
2004-09-30 12:19:59 +00:00
}
2008-08-06 05:34:55 +00:00
value = zend_ini_string ( " session.serialize_handler " , sizeof ( " session.serialize_handler " ) , 0 ) ;
if ( ! PS ( serializer ) & & value ) {
PS ( serializer ) = _php_find_ps_serializer ( value TSRMLS_CC ) ;
if ( ! PS ( serializer ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot find serialization handler '%s' - session startup failed " , value ) ;
return ;
}
}
PS ( session_status ) = php_session_none ;
/* fallthrough */
default :
case php_session_none :
PS ( define_sid ) = 1 ;
PS ( send_cookie ) = 1 ;
2003-06-10 03:56:23 +00:00
}
2002-05-09 20:02:47 +00:00
lensess = strlen ( PS ( session_name ) ) ;
2008-08-06 00:36:14 +00:00
2009-05-18 16:09:51 +00:00
/* Cookies are preferred, because initially
* cookie and get variables will be available . */
2002-05-09 20:02:47 +00:00
if ( ! PS ( id ) ) {
2009-05-18 16:09:51 +00:00
if ( PS ( use_cookies ) & & zend_ascii_hash_find ( & EG ( symbol_table ) , " _COOKIE " , sizeof ( " _COOKIE " ) , ( void * * ) & data ) = = SUCCESS & &
2002-05-09 20:02:47 +00:00
Z_TYPE_PP ( data ) = = IS_ARRAY & &
2009-05-18 16:09:51 +00:00
zend_ascii_hash_find ( Z_ARRVAL_PP ( data ) , PS ( session_name ) , lensess + 1 , ( void * * ) & ppid ) = = SUCCESS
) {
2002-05-09 20:02:47 +00:00
PPID2SID ;
PS ( apply_trans_sid ) = 0 ;
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 0 ;
2003-02-18 19:29:38 +00:00
PS ( define_sid ) = 0 ;
2002-05-09 20:02:47 +00:00
}
2002-06-12 08:18:36 +00:00
if ( ! PS ( use_only_cookies ) & & ! PS ( id ) & &
2009-05-18 16:09:51 +00:00
zend_ascii_hash_find ( & EG ( symbol_table ) , " _GET " , sizeof ( " _GET " ) , ( void * * ) & data ) = = SUCCESS & &
2002-05-09 20:02:47 +00:00
Z_TYPE_PP ( data ) = = IS_ARRAY & &
2009-05-18 16:09:51 +00:00
zend_rt_hash_find ( Z_ARRVAL_PP ( data ) , PS ( session_name ) , lensess + 1 , ( void * * ) & ppid ) = = SUCCESS
) {
2002-05-09 20:02:47 +00:00
PPID2SID ;
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 0 ;
2002-05-09 20:02:47 +00:00
}
2002-06-12 08:18:36 +00:00
if ( ! PS ( use_only_cookies ) & & ! PS ( id ) & &
2009-05-18 16:09:51 +00:00
zend_ascii_hash_find ( & EG ( symbol_table ) , " _POST " , sizeof ( " _POST " ) , ( void * * ) & data ) = = SUCCESS & &
2002-05-09 20:02:47 +00:00
Z_TYPE_PP ( data ) = = IS_ARRAY & &
2009-05-18 16:09:51 +00:00
zend_rt_hash_find ( Z_ARRVAL_PP ( data ) , PS ( session_name ) , lensess + 1 , ( void * * ) & ppid ) = = SUCCESS
) {
2002-05-09 20:02:47 +00:00
PPID2SID ;
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 0 ;
2002-05-09 20:02:47 +00:00
}
}
2009-05-18 16:09:51 +00:00
/* Check the REQUEST_URI symbol for a string of the form
* ' < session - name > = < session - id > ' to allow URLs of the form
* http : //yoursite/<session-name>=<session-id>/script.php */
1999-08-21 20:48:40 +00:00
2003-08-14 01:30:06 +00:00
if ( ! PS ( use_only_cookies ) & & ! PS ( id ) & & PG ( http_globals ) [ TRACK_VARS_SERVER ] & &
2009-05-18 16:09:51 +00:00
zend_ascii_hash_find ( Z_ARRVAL_P ( PG ( http_globals ) [ TRACK_VARS_SERVER ] ) , " REQUEST_URI " , sizeof ( " REQUEST_URI " ) , ( void * * ) & data ) = = SUCCESS & &
2000-09-06 14:13:31 +00:00
Z_TYPE_PP ( data ) = = IS_STRING & &
( p = strstr ( Z_STRVAL_PP ( data ) , PS ( session_name ) ) ) & &
2009-05-18 16:09:51 +00:00
p [ lensess ] = = ' = '
) {
1999-07-22 17:55:13 +00:00
char * q ;
p + = lensess + 1 ;
2007-01-04 22:04:38 +00:00
if ( ( q = strpbrk ( p , " /? \\ " ) ) ) {
1999-07-22 17:55:13 +00:00
PS ( id ) = estrndup ( p , q - p ) ;
2007-05-16 01:32:28 +00:00
PS ( send_cookie ) = 0 ;
2007-01-04 22:04:38 +00:00
}
1999-07-22 17:55:13 +00:00
}
1999-08-21 20:48:40 +00:00
2009-05-18 16:09:51 +00:00
/* Check whether the current request was referred to by
* an external site which invalidates the previously found id . */
2008-08-06 00:36:14 +00:00
2000-02-11 12:59:08 +00:00
if ( PS ( id ) & &
1999-08-21 20:48:40 +00:00
PS ( extern_referer_chk ) [ 0 ] ! = ' \0 ' & &
2003-08-14 01:30:06 +00:00
PG ( http_globals ) [ TRACK_VARS_SERVER ] & &
2009-05-18 16:09:51 +00:00
zend_hash_find ( Z_ARRVAL_P ( PG ( http_globals ) [ TRACK_VARS_SERVER ] ) , " HTTP_REFERER " , sizeof ( " HTTP_REFERER " ) , ( void * * ) & data ) = = SUCCESS & &
2000-09-06 14:13:31 +00:00
Z_TYPE_PP ( data ) = = IS_STRING & &
Z_STRLEN_PP ( data ) ! = 0 & &
2009-05-18 16:09:51 +00:00
strstr ( Z_STRVAL_PP ( data ) , PS ( extern_referer_chk ) ) = = NULL
) {
1999-08-21 20:48:40 +00:00
efree ( PS ( id ) ) ;
PS ( id ) = NULL ;
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 1 ;
2007-01-04 22:04:38 +00:00
if ( PS ( use_trans_sid ) ) {
2001-10-18 09:05:16 +00:00
PS ( apply_trans_sid ) = 1 ;
2007-01-04 22:04:38 +00:00
}
1999-08-21 20:48:40 +00:00
}
2008-08-06 00:36:14 +00:00
2002-03-29 16:00:27 +00:00
php_session_initialize ( TSRMLS_C ) ;
2008-08-06 00:36:14 +00:00
2003-02-18 19:13:49 +00:00
if ( ! PS ( use_cookies ) & & PS ( send_cookie ) ) {
2007-01-04 22:04:38 +00:00
if ( PS ( use_trans_sid ) ) {
2001-10-18 09:05:16 +00:00
PS ( apply_trans_sid ) = 1 ;
2007-01-04 22:04:38 +00:00
}
2003-02-18 19:13:49 +00:00
PS ( send_cookie ) = 0 ;
1999-10-22 08:10:08 +00:00
}
2001-07-11 13:46:11 +00:00
2003-02-18 19:29:38 +00:00
php_session_reset_id ( TSRMLS_C ) ;
2008-08-06 00:36:14 +00:00
2001-08-26 11:49:43 +00:00
PS ( session_status ) = php_session_active ;
1999-06-05 22:15:49 +00:00
2001-07-28 11:36:37 +00:00
php_session_cache_limiter ( TSRMLS_C ) ;
2002-02-03 05:40:19 +00:00
2002-03-06 09:02:31 +00:00
if ( PS ( mod_data ) & & PS ( gc_probability ) > 0 ) {
2000-03-29 20:37:29 +00:00
int nrdels = - 1 ;
2002-03-06 09:02:31 +00:00
2003-04-05 11:22:15 +00:00
nrand = ( int ) ( ( float ) PS ( gc_divisor ) * php_combined_lcg ( TSRMLS_C ) ) ;
2001-07-25 19:02:13 +00:00
if ( nrand < PS ( gc_probability ) ) {
2003-02-11 00:42:14 +00:00
PS ( mod ) - > s_gc ( & PS ( mod_data ) , PS ( gc_maxlifetime ) , & nrdels TSRMLS_CC ) ;
2007-01-04 22:04:38 +00:00
# ifdef SESSION_DEBUG
if ( nrdels ! = - 1 ) {
2003-08-28 20:43:18 +00:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " purged %d expired session objects " , nrdels ) ;
2007-01-04 22:04:38 +00:00
}
2000-09-20 01:38:39 +00:00
# endif
2002-05-09 20:02:47 +00:00
}
}
1999-06-07 16:43:24 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-06-07 16:43:24 +00:00
2008-08-06 00:36:14 +00:00
static void php_session_flush ( TSRMLS_D ) /* { { { */
1999-06-07 16:43:24 +00:00
{
2007-01-04 22:04:38 +00:00
if ( PS ( session_status ) = = php_session_active ) {
PS ( session_status ) = php_session_none ;
zend_try {
php_session_save_current_state ( TSRMLS_C ) ;
} zend_end_try ( ) ;
2002-05-09 20:02:47 +00:00
}
2007-01-04 22:04:38 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2002-05-09 19:42:00 +00:00
2008-08-06 00:36:14 +00:00
PHPAPI void session_adapt_url ( const char * url , size_t urllen , char * * new , size_t * newlen TSRMLS_DC ) /* { { { */
2007-01-04 22:04:38 +00:00
{
if ( PS ( apply_trans_sid ) & & ( PS ( session_status ) = = php_session_active ) ) {
* new = php_url_scanner_adapt_single_url ( url , urllen , PS ( session_name ) , PS ( id ) , newlen TSRMLS_CC ) ;
}
1999-06-05 22:15:49 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-06-05 22:15:49 +00:00
2007-01-04 22:04:38 +00:00
/* ********************************
* Userspace exported functions *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-01-05 02:07:59 +00:00
/* {{{ proto void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly]]]]) U
2000-02-04 23:34:24 +00:00
Set session cookie parameters */
2008-08-06 04:24:55 +00:00
static PHP_FUNCTION ( session_set_cookie_params )
2000-02-04 23:34:24 +00:00
{
2009-05-18 16:09:51 +00:00
zval * * lifetime = NULL ;
char * path = NULL , * domain = NULL ;
int path_len , domain_len , argc = ZEND_NUM_ARGS ( ) ;
2007-01-04 22:04:38 +00:00
zend_bool secure = 0 , httponly = 0 ;
if ( ! PS ( use_cookies ) | |
2009-05-18 16:09:51 +00:00
zend_parse_parameters ( argc TSRMLS_CC , " Z|ssbb " , & lifetime , & path , & path_len , & domain , & domain_len , & secure , & httponly ) = = FAILURE ) {
2002-05-09 20:02:47 +00:00
return ;
2007-01-04 22:04:38 +00:00
}
2000-02-04 23:34:24 +00:00
2009-05-18 16:09:51 +00:00
convert_to_string_ex ( lifetime ) ;
zend_alter_ini_entry ( " session.cookie_lifetime " , sizeof ( " session.cookie_lifetime " ) , Z_STRVAL_PP ( lifetime ) , Z_STRLEN_PP ( lifetime ) , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2002-05-09 20:02:47 +00:00
2007-01-04 22:04:38 +00:00
if ( path ) {
zend_alter_ini_entry ( " session.cookie_path " , sizeof ( " session.cookie_path " ) , path , path_len , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
if ( domain ) {
zend_alter_ini_entry ( " session.cookie_domain " , sizeof ( " session.cookie_domain " ) , domain , domain_len , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
2002-05-09 20:02:47 +00:00
2007-01-04 22:04:38 +00:00
if ( argc > 3 ) {
zend_alter_ini_entry ( " session.cookie_secure " , sizeof ( " session.cookie_secure " ) , secure ? " 1 " : " 0 " , 1 , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
}
if ( argc > 4 ) {
zend_alter_ini_entry ( " session.cookie_httponly " , sizeof ( " session.cookie_httponly " ) , httponly ? " 1 " : " 0 " , 1 , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2002-05-09 20:02:47 +00:00
}
2000-02-04 23:34:24 +00:00
}
/* }}} */
2007-01-05 02:07:59 +00:00
/* {{{ proto array session_get_cookie_params(void) U
2009-05-18 16:09:51 +00:00
Return the session cookie parameters */
2008-08-06 04:24:55 +00:00
static PHP_FUNCTION ( session_get_cookie_params )
2000-03-30 20:02:21 +00:00
{
2008-02-28 14:16:25 +00:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-05-09 20:02:47 +00:00
}
2003-01-18 19:28:10 +00:00
array_init ( return_value ) ;
2002-05-09 20:02:47 +00:00
2006-09-19 10:38:31 +00:00
add_ascii_assoc_long ( return_value , " lifetime " , PS ( cookie_lifetime ) ) ;
add_ascii_assoc_rt_string ( return_value , " path " , PS ( cookie_path ) , 1 ) ;
add_ascii_assoc_rt_string ( return_value , " domain " , PS ( cookie_domain ) , 1 ) ;
add_ascii_assoc_bool ( return_value , " secure " , PS ( cookie_secure ) ) ;
add_ascii_assoc_bool ( return_value , " httponly " , PS ( cookie_httponly ) ) ;
2000-03-30 18:50:09 +00:00
}
/* }}} */
2000-02-04 23:34:24 +00:00
2007-01-05 02:07:59 +00:00
/* {{{ proto string session_name([string newname]) U
2000-06-23 17:37:49 +00:00
Return the current session name . If newname is given , the session name is replaced with newname */
2008-08-06 04:24:55 +00:00
static PHP_FUNCTION ( session_name )
1999-06-05 19:52:58 +00:00
{
2007-01-04 22:04:38 +00:00
char * name = NULL ;
int name_len ;
1999-06-05 19:52:58 +00:00
2007-01-05 02:07:59 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s& " , & name , & name_len , UG ( utf8_conv ) ) = = FAILURE ) {
2007-01-04 22:04:38 +00:00
return ;
}
2008-08-06 00:36:14 +00:00
2007-01-05 02:07:59 +00:00
RETVAL_UTF8_STRING ( PS ( session_name ) , ZSTR_DUPLICATE ) ;
2002-05-09 19:42:00 +00:00
2007-01-04 22:04:38 +00:00
if ( name ) {
zend_alter_ini_entry ( " session.name " , sizeof ( " session.name " ) , name , name_len , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2002-05-09 20:02:47 +00:00
}
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-05 02:07:59 +00:00
/* {{{ proto string session_module_name([string newname]) U
2000-06-23 17:37:49 +00:00
Return the current module name used for accessing session data . If newname is given , the module name is replaced with newname */
2008-08-06 04:24:55 +00:00
static PHP_FUNCTION ( session_module_name )
1999-06-05 19:52:58 +00:00
{
2007-01-04 22:04:38 +00:00
char * name = NULL ;
int name_len ;
2002-05-09 20:02:47 +00:00
2007-01-05 02:07:59 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s& " , & name , & name_len , UG ( utf8_conv ) ) = = FAILURE ) {
2007-01-04 22:04:38 +00:00
return ;
2005-06-03 22:09:22 +00:00
}
2002-05-09 20:02:47 +00:00
2005-06-03 22:09:22 +00:00
/* Set return_value to current module name */
if ( PS ( mod ) & & PS ( mod ) - > s_name ) {
2007-01-05 02:07:59 +00:00
RETVAL_UTF8_STRING ( ( char * ) PS ( mod ) - > s_name , ZSTR_DUPLICATE ) ;
2005-06-03 22:09:22 +00:00
} else {
RETVAL_EMPTY_STRING ( ) ;
}
2008-08-06 00:36:14 +00:00
2007-01-04 22:04:38 +00:00
if ( name ) {
if ( ! _php_find_ps_module ( name TSRMLS_CC ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot find named PHP session module (%s) " , name ) ;
2006-08-30 15:42:40 +00:00
zval_dtor ( return_value ) ;
2002-05-09 20:02:47 +00:00
RETURN_FALSE ;
}
2004-04-13 18:18:22 +00:00
if ( PS ( mod_data ) ) {
PS ( mod ) - > s_close ( & PS ( mod_data ) TSRMLS_CC ) ;
}
PS ( mod_data ) = NULL ;
2002-05-09 20:02:47 +00:00
2007-01-04 22:04:38 +00:00
zend_alter_ini_entry ( " session.save_handler " , sizeof ( " session.save_handler " ) , name , name_len , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2004-04-13 18:18:22 +00:00
}
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-05 02:07:59 +00:00
/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc) U
2000-02-24 15:11:09 +00:00
Sets user - level functions */
2008-08-06 04:24:55 +00:00
static PHP_FUNCTION ( session_set_save_handler )
1999-09-17 05:40:59 +00:00
{
2008-08-06 04:48:39 +00:00
zval * * * args = NULL ;
int i , num_args , argc = ZEND_NUM_ARGS ( ) ;
2005-08-22 12:22:16 +00:00
zval name ;
2002-05-09 19:42:00 +00:00
2007-01-04 22:04:38 +00:00
if ( PS ( session_status ) ! = php_session_none ) {
2002-05-09 20:02:47 +00:00
RETURN_FALSE ;
2007-01-04 22:04:38 +00:00
}
2008-08-06 04:48:39 +00:00
if ( argc ! = 6 ) {
2007-01-04 22:04:38 +00:00
WRONG_PARAM_COUNT ;
}
2008-08-06 00:36:14 +00:00
2008-08-06 04:48:39 +00:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " + " , & args , & num_args ) = = FAILURE ) {
return ;
}
2007-01-04 22:04:38 +00:00
2005-01-09 17:42:02 +00:00
for ( i = 0 ; i < 6 ; i + + ) {
2008-08-02 04:40:45 +00:00
if ( ! zend_is_callable ( * args [ i ] , 0 , & name TSRMLS_CC ) ) {
2008-08-06 04:48:39 +00:00
efree ( args ) ;
2005-01-09 17:42:02 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Argument %d is not a valid callback " , i + 1 ) ;
2005-08-22 12:22:16 +00:00
zval_dtor ( & name ) ;
2005-01-09 17:42:02 +00:00
RETURN_FALSE ;
2005-01-09 17:49:51 +00:00
}
2005-08-22 12:22:16 +00:00
zval_dtor ( & name ) ;
2005-01-09 17:42:02 +00:00
}
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
zend_alter_ini_entry ( " session.save_handler " , sizeof ( " session.save_handler " ) , " user " , sizeof ( " user " ) - 1 , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2002-05-09 19:42:00 +00:00
2002-05-09 20:02:47 +00:00
for ( i = 0 ; i < 6 ; i + + ) {
2008-03-07 23:20:15 +00:00
if ( PS ( mod_user_names ) . names [ i ] ! = NULL ) {
zval_ptr_dtor ( & PS ( mod_user_names ) . names [ i ] ) ;
}
2008-08-06 04:48:39 +00:00
Z_ADDREF_PP ( args [ i ] ) ;
2008-03-07 23:20:15 +00:00
PS ( mod_user_names ) . names [ i ] = * args [ i ] ;
2002-05-09 20:02:47 +00:00
}
2008-08-06 00:36:14 +00:00
2008-08-06 04:48:39 +00:00
efree ( args ) ;
2002-05-09 20:02:47 +00:00
RETURN_TRUE ;
1999-09-17 05:40:59 +00:00
}
/* }}} */
2007-01-05 02:07:59 +00:00
/* {{{ proto string session_save_path([string newname]) U
2000-06-23 17:37:49 +00:00
Return the current save path passed to module_name . If newname is given , the save path is replaced with newname */
2008-08-06 04:24:55 +00:00
static PHP_FUNCTION ( session_save_path )
1999-06-05 19:52:58 +00:00
{
2008-04-15 00:32:51 +00:00
char * name = NULL ;
2007-01-04 22:04:38 +00:00
int name_len ;
2002-05-09 19:42:00 +00:00
2007-01-05 02:07:59 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s& " , & name , & name_len , UG ( utf8_conv ) ) = = FAILURE ) {
2007-01-04 22:04:38 +00:00
return ;
}
2002-05-09 19:42:00 +00:00
2007-01-05 02:07:59 +00:00
RETVAL_UTF8_STRING ( PS ( save_path ) , ZSTR_DUPLICATE ) ;
2007-01-04 22:04:38 +00:00
if ( name ) {
if ( memchr ( name , ' \0 ' , name_len ) ! = NULL ) {
2008-08-05 22:52:35 +00:00
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " The save_path cannot contain NULL characters " ) ;
2007-01-04 22:04:38 +00:00
zval_dtor ( return_value ) ;
2006-12-26 17:18:28 +00:00
RETURN_FALSE ;
}
2007-01-04 22:04:38 +00:00
zend_alter_ini_entry ( " session.save_path " , sizeof ( " session.save_path " ) , name , name_len , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2002-05-09 20:02:47 +00:00
}
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-05 02:07:59 +00:00
/* {{{ proto string session_id([string newid]) U
2000-06-23 17:37:49 +00:00
Return the current session id . If newid is given , the session id is replaced with newid */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_id )
1999-06-05 19:52:58 +00:00
{
2007-01-05 02:07:59 +00:00
zstr name = NULL_ZSTR ;
2007-01-04 22:04:38 +00:00
int name_len ;
2007-01-05 02:07:59 +00:00
zend_uchar name_type ;
2002-03-06 09:02:31 +00:00
2007-01-05 02:07:59 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |t " , & name , & name_len , & name_type ) = = FAILURE ) {
2007-01-04 22:04:38 +00:00
return ;
}
2002-03-06 12:34:47 +00:00
2007-01-05 02:07:59 +00:00
if ( name . v ) {
char * old = PS ( id ) ;
2002-05-09 19:42:00 +00:00
2007-01-05 02:07:59 +00:00
if ( name_type = = IS_STRING ) {
PS ( id ) = estrndup ( name . s , name_len ) ;
} else {
/* IS_UNICODE */
char * id = NULL ;
int id_len ;
UErrorCode status = U_ZERO_ERROR ;
2007-01-05 14:53:30 +00:00
zend_unicode_to_string_ex ( ZEND_U_CONVERTER ( UG ( runtime_encoding_conv ) ) , & id , & id_len , name . u , name_len , & status ) ;
2007-01-05 02:07:59 +00:00
if ( U_SUCCESS ( status ) & & id ) {
PS ( id ) = id ;
} else {
if ( id ) {
efree ( id ) ;
}
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Session ID must be either binary or a unicode string made up exclusively of ASCII " ) ;
RETURN_FALSE ;
}
}
if ( old ) {
RETURN_STRING ( old , 0 ) ;
} else {
RETURN_EMPTY_STRING ( ) ;
}
} else if ( PS ( id ) ) {
RETURN_STRING ( PS ( id ) , 1 ) ;
} else {
RETURN_EMPTY_STRING ( ) ;
2002-05-09 20:02:47 +00:00
}
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-05 02:07:59 +00:00
/* {{{ proto bool session_regenerate_id([bool delete_old_session]) U
2005-05-29 16:51:25 +00:00
Update the current session id with a newly generated one . If delete_old_session is set to true , remove the old session . */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_regenerate_id )
2003-02-18 18:50:44 +00:00
{
2005-05-29 16:51:25 +00:00
zend_bool del_ses = 0 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |b " , & del_ses ) = = FAILURE ) {
2006-10-07 22:55:18 +00:00
return ;
2005-05-29 16:51:25 +00:00
}
2006-05-18 22:07:31 +00:00
if ( SG ( headers_sent ) ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Cannot regenerate session id - headers already sent " ) ;
RETURN_FALSE ;
}
2003-02-18 19:13:49 +00:00
if ( PS ( session_status ) = = php_session_active ) {
2005-05-29 16:51:25 +00:00
if ( PS ( id ) ) {
if ( del_ses & & PS ( mod ) - > s_destroy ( & PS ( mod_data ) , PS ( id ) TSRMLS_CC ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_WARNING , " Session object destruction failed " ) ;
RETURN_FALSE ;
}
efree ( PS ( id ) ) ;
2007-03-19 08:24:17 +00:00
PS ( id ) = NULL ;
2005-05-29 16:51:25 +00:00
}
2008-08-06 00:36:14 +00:00
2003-02-18 18:50:44 +00:00
PS ( id ) = PS ( mod ) - > s_create_sid ( & PS ( mod_data ) , NULL TSRMLS_CC ) ;
2003-02-18 19:13:49 +00:00
2006-02-10 07:41:59 +00:00
PS ( send_cookie ) = 1 ;
2003-02-18 19:29:38 +00:00
php_session_reset_id ( TSRMLS_C ) ;
2008-08-06 00:36:14 +00:00
2003-02-18 18:50:44 +00:00
RETURN_TRUE ;
}
RETURN_FALSE ;
}
/* }}} */
2007-01-05 02:07:59 +00:00
/* {{{ proto string session_cache_limiter([string new_cache_limiter]) U
2000-09-01 15:56:26 +00:00
Return the current cache limiter . If new_cache_limited is given , the current cache_limiter is replaced with new_cache_limiter */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_cache_limiter )
2000-09-01 15:56:26 +00:00
{
2008-04-15 00:39:43 +00:00
char * limiter = NULL ;
2007-01-04 22:04:38 +00:00
int limiter_len ;
2000-09-01 15:56:26 +00:00
2007-01-05 02:07:59 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " |s& " , & limiter , & limiter_len , UG ( utf8_conv ) ) = = FAILURE ) {
2007-01-04 22:04:38 +00:00
return ;
}
2002-05-09 19:42:00 +00:00
2007-01-05 02:07:59 +00:00
RETVAL_UTF8_STRING ( PS ( cache_limiter ) , 1 ) ;
2007-01-04 22:04:38 +00:00
if ( limiter ) {
zend_alter_ini_entry ( " session.cache_limiter " , sizeof ( " session.cache_limiter " ) , limiter , limiter_len , PHP_INI_USER , PHP_INI_STAGE_RUNTIME ) ;
2002-05-09 20:02:47 +00:00
}
2000-09-01 15:56:26 +00:00
}
/* }}} */
2007-01-05 02:07:59 +00:00
/* {{{ proto int session_cache_expire([int new_cache_expire]) U
2001-10-22 15:18:06 +00:00
Return the current cache expire . If new_cache_expire is given , the current cache_expire is replaced with new_cache_expire */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_cache_expire )
2001-10-22 15:18:06 +00:00
{
2009-05-18 16:09:51 +00:00
zval * * expires = NULL ;
int argc = ZEND_NUM_ARGS ( ) ;
2002-03-06 09:02:31 +00:00
2009-05-18 16:09:51 +00:00
if ( zend_parse_parameters ( argc TSRMLS_CC , " |Z " , & expires ) = = FAILURE ) {
2007-01-04 22:04:38 +00:00
return ;
}
2001-10-22 15:18:06 +00:00
2007-01-04 22:04:38 +00:00
RETVAL_LONG ( PS ( cache_expire ) ) ;
2001-10-22 15:18:06 +00:00
2009-05-18 16:09:51 +00:00
if ( argc = = 1 ) {
convert_to_string_ex ( expires ) ;
zend_alter_ini_entry ( " session.cache_expire " , sizeof ( " session.cache_expire " ) , Z_STRVAL_PP ( expires ) , Z_STRLEN_PP ( expires ) , ZEND_INI_USER , ZEND_INI_STAGE_RUNTIME ) ;
2002-05-09 20:02:47 +00:00
}
2001-10-22 15:18:06 +00:00
}
/* }}} */
2001-07-28 11:36:37 +00:00
/* {{{ static void php_register_var(zval** entry TSRMLS_DC) */
static void php_register_var ( zval * * entry TSRMLS_DC )
1999-11-27 21:18:41 +00:00
{
2002-05-09 20:02:47 +00:00
zval * * value ;
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
if ( Z_TYPE_PP ( entry ) = = IS_ARRAY ) {
zend_hash_internal_pointer_reset ( Z_ARRVAL_PP ( entry ) ) ;
while ( zend_hash_get_current_data ( Z_ARRVAL_PP ( entry ) , ( void * * ) & value ) = = SUCCESS ) {
php_register_var ( value TSRMLS_CC ) ;
zend_hash_move_forward ( Z_ARRVAL_PP ( entry ) ) ;
}
} else {
convert_to_string_ex ( entry ) ;
2006-12-20 19:20:59 +00:00
if ( strcmp ( Z_STRVAL_PP ( entry ) , " _SESSION " ) ! = 0 ) {
2002-05-09 20:02:47 +00:00
PS_ADD_VARL ( Z_STRVAL_PP ( entry ) , Z_STRLEN_PP ( entry ) ) ;
}
}
1999-11-27 21:18:41 +00:00
}
/* }}} */
2007-01-05 02:07:59 +00:00
/* {{{ proto string session_encode(void) U
2000-02-24 15:11:09 +00:00
Serializes the current setup and returns the serialized representation */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_encode )
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
int len ;
char * enc ;
1999-06-05 19:52:58 +00:00
2008-02-28 14:16:25 +00:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-05-09 20:02:47 +00:00
}
2001-08-13 06:43:47 +00:00
2002-05-09 20:02:47 +00:00
enc = php_session_encode ( & len TSRMLS_CC ) ;
2002-09-29 15:55:11 +00:00
if ( enc = = NULL ) {
RETURN_FALSE ;
}
2008-08-06 00:36:14 +00:00
2007-01-05 02:07:59 +00:00
RETVAL_UTF8_STRINGL ( enc , len , ZSTR_AUTOFREE ) ;
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-05 02:07:59 +00:00
/* {{{ proto bool session_decode(string data) U
2000-02-24 15:11:09 +00:00
Deserializes data and reinitializes the variables */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_decode )
1999-06-05 19:52:58 +00:00
{
2007-01-04 22:04:38 +00:00
char * str ;
int str_len ;
1999-06-05 19:52:58 +00:00
2002-12-29 18:50:55 +00:00
if ( PS ( session_status ) = = php_session_none ) {
2002-10-03 15:33:00 +00:00
RETURN_FALSE ;
2002-12-29 18:50:55 +00:00
}
2002-10-03 15:33:00 +00:00
2007-01-05 02:07:59 +00:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s& " , & str , & str_len , UG ( utf8_conv ) ) = = FAILURE ) {
2007-01-04 22:04:38 +00:00
return ;
}
1999-09-17 09:26:03 +00:00
2007-01-04 22:04:38 +00:00
php_session_decode ( str , str_len TSRMLS_CC ) ;
2008-08-06 00:36:14 +00:00
2002-12-29 18:50:55 +00:00
RETURN_TRUE ;
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-05 02:07:59 +00:00
/* {{{ proto bool session_start(void) U
1999-06-06 14:19:55 +00:00
Begin session - reinitializes freezed variables , registers browsers etc */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_start )
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
/* skipping check for non-zero args for performance reasons here ?*/
php_session_start ( TSRMLS_C ) ;
2008-08-06 05:34:55 +00:00
if ( PS ( session_status ) ! = php_session_active ) {
RETURN_FALSE ;
}
2002-05-09 20:02:47 +00:00
RETURN_TRUE ;
1999-06-05 19:52:58 +00:00
}
1999-06-06 14:19:55 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-05 02:07:59 +00:00
/* {{{ proto bool session_destroy(void) U
1999-06-07 16:43:24 +00:00
Destroy the current session and all data associated with it */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_destroy )
1999-06-07 16:43:24 +00:00
{
2008-02-28 14:16:25 +00:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-05-09 20:02:47 +00:00
}
2007-01-04 22:04:38 +00:00
RETURN_BOOL ( php_session_destroy ( TSRMLS_C ) = = SUCCESS ) ;
1999-06-07 16:43:24 +00:00
}
/* }}} */
2007-01-05 02:07:59 +00:00
/* {{{ proto void session_unset(void) U
1999-09-11 22:31:04 +00:00
Unset all registered variables */
2007-01-04 22:04:38 +00:00
static PHP_FUNCTION ( session_unset )
1999-09-11 22:31:04 +00:00
{
2007-01-04 22:04:38 +00:00
if ( PS ( session_status ) = = php_session_none ) {
2002-05-09 20:02:47 +00:00
RETURN_FALSE ;
2007-01-04 22:04:38 +00:00
}
2002-05-09 20:02:47 +00:00
2002-10-03 03:23:02 +00:00
IF_SESSION_VARS ( ) {
2009-12-04 01:21:32 +00:00
HashTable * ht ;
SEPARATE_ZVAL_IF_NOT_REF ( & PS ( http_session_vars ) ) ;
ht = Z_ARRVAL_P ( PS ( http_session_vars ) ) ;
2002-10-03 03:23:02 +00:00
/* Clean $_SESSION. */
zend_hash_clean ( ht ) ;
2002-05-09 20:02:47 +00:00
}
1999-09-11 22:31:04 +00:00
}
/* }}} */
2007-01-05 02:07:59 +00:00
/* {{{ proto void session_write_close(void) U
2007-01-04 22:04:38 +00:00
Write session data and end session */
static PHP_FUNCTION ( session_write_close )
2002-05-05 16:39:49 +00:00
{
2007-01-04 22:04:38 +00:00
php_session_flush ( TSRMLS_C ) ;
2002-05-05 16:39:49 +00:00
}
2007-01-04 22:04:38 +00:00
/* }}} */
2001-08-31 20:03:09 +00:00
2008-06-27 16:37:03 +00:00
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_name , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , name )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_module_name , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , module )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_save_path , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , path )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_id , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , id )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_regenerate_id , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , delete_old_session )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_decode , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , data )
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 , 6 )
ZEND_ARG_INFO ( 0 , open )
ZEND_ARG_INFO ( 0 , close )
ZEND_ARG_INFO ( 0 , read )
ZEND_ARG_INFO ( 0 , write )
ZEND_ARG_INFO ( 0 , destroy )
ZEND_ARG_INFO ( 0 , gc )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_cache_limiter , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , cache_limiter )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_cache_expire , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , new_cache_expire )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_session_set_cookie_params , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , lifetime )
ZEND_ARG_INFO ( 0 , path )
ZEND_ARG_INFO ( 0 , domain )
ZEND_ARG_INFO ( 0 , secure )
ZEND_ARG_INFO ( 0 , httponly )
ZEND_END_ARG_INFO ( )
/* }}} */
2007-01-04 22:04:38 +00:00
/* {{{ session_functions[]
*/
2007-09-27 18:28:44 +00:00
static const zend_function_entry session_functions [ ] = {
2008-06-27 16:37:03 +00:00
PHP_FE ( session_name , arginfo_session_name )
PHP_FE ( session_module_name , arginfo_session_module_name )
PHP_FE ( session_save_path , arginfo_session_save_path )
PHP_FE ( session_id , arginfo_session_id )
PHP_FE ( session_regenerate_id , arginfo_session_regenerate_id )
PHP_FE ( session_decode , arginfo_session_decode )
PHP_FE ( session_encode , arginfo_session_void )
PHP_FE ( session_start , arginfo_session_void )
PHP_FE ( session_destroy , arginfo_session_void )
PHP_FE ( session_unset , arginfo_session_void )
PHP_FE ( session_set_save_handler , arginfo_session_set_save_handler )
PHP_FE ( session_cache_limiter , arginfo_session_cache_limiter )
PHP_FE ( session_cache_expire , arginfo_session_cache_expire )
PHP_FE ( session_set_cookie_params , arginfo_session_set_cookie_params )
PHP_FE ( session_get_cookie_params , arginfo_session_void )
PHP_FE ( session_write_close , arginfo_session_void )
PHP_FALIAS ( session_commit , session_write_close , arginfo_session_void )
2009-05-18 16:09:51 +00:00
{ NULL , NULL , NULL }
2007-01-04 22:04:38 +00:00
} ;
/* }}} */
1999-06-05 19:52:58 +00:00
2007-01-04 22:04:38 +00:00
/* ********************************
* Module Setup and Destruction *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-11 11:51:07 +00:00
static inline int php_rinit_session ( zend_bool auto_start TSRMLS_DC ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
php_rinit_session_globals ( TSRMLS_C ) ;
1999-06-06 18:22:17 +00:00
2002-05-09 20:02:47 +00:00
if ( PS ( mod ) = = NULL ) {
char * value ;
2001-05-23 23:18:51 +00:00
2002-05-09 20:02:47 +00:00
value = zend_ini_string ( " session.save_handler " , sizeof ( " session.save_handler " ) , 0 ) ;
if ( value ) {
PS ( mod ) = _php_find_ps_module ( value TSRMLS_CC ) ;
}
2008-08-04 06:18:27 +00:00
}
if ( PS ( serializer ) = = NULL ) {
char * value ;
2001-05-23 23:18:51 +00:00
2008-08-04 06:18:27 +00:00
value = zend_ini_string ( " session.serialize_handler " , sizeof ( " session.serialize_handler " ) , 0 ) ;
2008-08-06 00:36:14 +00:00
if ( value ) {
2008-08-04 06:18:27 +00:00
PS ( serializer ) = _php_find_ps_serializer ( value TSRMLS_CC ) ;
2002-05-09 20:02:47 +00:00
}
}
1999-08-27 21:03:22 +00:00
2008-08-04 06:18:27 +00:00
if ( PS ( mod ) = = NULL | | PS ( serializer ) = = NULL ) {
/* current status is unusable */
PS ( session_status ) = php_session_disabled ;
return SUCCESS ;
}
2008-09-11 11:51:07 +00:00
if ( auto_start ) {
2002-05-09 20:02:47 +00:00
php_session_start ( TSRMLS_C ) ;
}
1999-06-05 19:52:58 +00:00
2002-05-09 20:02:47 +00:00
return SUCCESS ;
2008-09-11 11:51:07 +00:00
} /* }}} */
static PHP_RINIT_FUNCTION ( session ) /* { { { */
{
return php_rinit_session ( PS ( auto_start ) TSRMLS_CC ) ;
2000-01-16 21:03:49 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
2000-01-15 13:09:32 +00:00
2008-08-06 00:36:14 +00:00
static PHP_RSHUTDOWN_FUNCTION ( session ) /* { { { */
2000-10-11 19:47:15 +00:00
{
2008-03-07 23:20:15 +00:00
int i ;
2008-08-06 00:36:14 +00:00
2005-09-23 08:13:57 +00:00
php_session_flush ( TSRMLS_C ) ;
php_rshutdown_session_globals ( TSRMLS_C ) ;
2008-08-06 00:36:14 +00:00
2008-03-07 23:20:15 +00:00
/* 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 ] ) ;
2008-03-11 09:36:51 +00:00
PS ( mod_user_names ) . names [ i ] = NULL ;
2008-03-07 23:20:15 +00:00
}
}
2005-09-20 20:56:21 +00:00
1999-06-05 19:52:58 +00:00
return SUCCESS ;
}
2001-12-04 22:57:16 +00:00
/* }}} */
2000-01-16 21:03:49 +00:00
2008-08-06 00:36:14 +00:00
static PHP_GINIT_FUNCTION ( ps ) /* { { { */
2004-02-24 08:47:35 +00:00
{
2008-03-07 23:20:15 +00:00
int i ;
2008-08-06 00:36:14 +00:00
2004-02-24 08:47:35 +00:00
ps_globals - > save_path = NULL ;
ps_globals - > session_name = NULL ;
ps_globals - > id = NULL ;
ps_globals - > mod = NULL ;
2008-08-06 00:36:14 +00:00
ps_globals - > serializer = NULL ;
2004-02-24 08:47:35 +00:00
ps_globals - > mod_data = NULL ;
ps_globals - > session_status = php_session_none ;
2008-03-07 23:20:15 +00:00
for ( i = 0 ; i < 6 ; i + + ) {
ps_globals - > mod_user_names . names [ i ] = NULL ;
}
2004-02-24 08:47:35 +00:00
ps_globals - > http_session_vars = NULL ;
}
2008-08-06 05:34:55 +00:00
/* }}} */
2000-01-16 21:03:49 +00:00
2008-08-06 00:36:14 +00:00
static PHP_MINIT_FUNCTION ( session ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2003-03-02 10:19:15 +00:00
zend_register_auto_global ( " _SESSION " , sizeof ( " _SESSION " ) - 1 , NULL TSRMLS_CC ) ;
2001-08-11 10:49:03 +00:00
2002-05-05 16:39:49 +00:00
PS ( module_number ) = module_number ; /* if we really need this var we need to init it in zts mode as well! */
2002-06-28 02:27:02 +00:00
2003-01-08 13:28:16 +00:00
PS ( session_status ) = php_session_none ;
1999-06-05 19:52:58 +00:00
REGISTER_INI_ENTRIES ( ) ;
2002-06-28 02:27:02 +00:00
# ifdef HAVE_LIBMM
PHP_MINIT ( ps_mm ) ( INIT_FUNC_ARGS_PASSTHRU ) ;
# endif
2008-09-11 11:51:07 +00:00
php_session_rfc1867_orig_callback = php_rfc1867_callback ;
php_rfc1867_callback = php_session_rfc1867_callback ;
1999-06-05 19:52:58 +00:00
return SUCCESS ;
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-06-05 19:52:58 +00:00
2008-08-06 00:36:14 +00:00
static PHP_MSHUTDOWN_FUNCTION ( session ) /* { { { */
1999-06-05 19:52:58 +00:00
{
2002-05-09 20:02:47 +00:00
UNREGISTER_INI_ENTRIES ( ) ;
2002-06-28 02:27:02 +00:00
# ifdef HAVE_LIBMM
PHP_MSHUTDOWN ( ps_mm ) ( SHUTDOWN_FUNC_ARGS_PASSTHRU ) ;
# endif
2004-12-07 18:02:25 +00:00
ps_serializers [ PREDEFINED_SERIALIZERS ] . name = NULL ;
2005-09-20 14:05:16 +00:00
memset ( & ps_modules [ PREDEFINED_MODULES ] , 0 , ( MAX_MODULES - PREDEFINED_MODULES ) * sizeof ( ps_module * ) ) ;
2004-12-07 18:02:25 +00:00
2002-05-09 20:02:47 +00:00
return SUCCESS ;
1999-06-05 19:52:58 +00:00
}
2008-08-06 00:36:14 +00:00
/* }}} */
1999-06-06 19:53:59 +00:00
2008-08-06 00:36:14 +00:00
static PHP_MINFO_FUNCTION ( session ) /* { { { */
1999-06-06 19:53:59 +00:00
{
2002-06-28 02:27:02 +00:00
ps_module * * mod ;
2003-08-26 02:03:41 +00:00
ps_serializer * ser ;
smart_str save_handlers = { 0 } ;
smart_str ser_handlers = { 0 } ;
2002-06-28 02:27:02 +00:00
int i ;
2008-08-06 00:36:14 +00:00
2003-08-26 02:03:41 +00:00
/* Get save handlers */
2002-06-28 02:27:02 +00:00
for ( i = 0 , mod = ps_modules ; i < MAX_MODULES ; i + + , mod + + ) {
2003-02-11 00:42:14 +00:00
if ( * mod & & ( * mod ) - > s_name ) {
2003-08-26 02:03:41 +00:00
smart_str_appends ( & save_handlers , ( * mod ) - > s_name ) ;
smart_str_appendc ( & save_handlers , ' ' ) ;
}
}
/* Get serializer handlers */
for ( i = 0 , ser = ps_serializers ; i < MAX_SERIALIZERS ; i + + , ser + + ) {
if ( ser & & ser - > name ) {
smart_str_appends ( & ser_handlers , ser - > name ) ;
smart_str_appendc ( & ser_handlers , ' ' ) ;
2002-06-28 02:27:02 +00:00
}
}
2008-08-06 00:36:14 +00:00
2002-05-09 20:02:47 +00:00
php_info_print_table_start ( ) ;
php_info_print_table_row ( 2 , " Session Support " , " enabled " ) ;
2002-06-28 02:27:02 +00:00
2003-08-26 02:03:41 +00:00
if ( save_handlers . c ) {
smart_str_0 ( & save_handlers ) ;
php_info_print_table_row ( 2 , " Registered save handlers " , save_handlers . c ) ;
smart_str_free ( & save_handlers ) ;
2002-06-28 02:27:02 +00:00
} else {
php_info_print_table_row ( 2 , " Registered save handlers " , " none " ) ;
}
2003-08-26 02:03:41 +00:00
if ( ser_handlers . c ) {
smart_str_0 ( & ser_handlers ) ;
php_info_print_table_row ( 2 , " Registered serializer handlers " , ser_handlers . c ) ;
smart_str_free ( & ser_handlers ) ;
} else {
php_info_print_table_row ( 2 , " Registered serializer handlers " , " none " ) ;
}
2002-05-09 20:02:47 +00:00
php_info_print_table_end ( ) ;
2000-04-06 21:07:44 +00:00
2002-05-09 20:02:47 +00:00
DISPLAY_INI_ENTRIES ( ) ;
1999-06-06 19:53:59 +00:00
}
2008-08-06 05:34:55 +00:00
/* }}} */
2001-06-06 14:32:27 +00:00
2008-09-11 11:51:07 +00:00
/* ************************
* Upload hook handling *
* * * * * * * * * * * * * * * * * * * * * * * * */
# define USTR_EQUAL(s1, len1, s2, len2) \
2009-03-26 20:02:53 +00:00
( ( len1 ) = = ( len2 ) & & zend_u_binary_strcmp ( ( s1 ) . u , ( len1 ) , ( s2 ) . u , ( len2 ) ) = = 0 )
2008-09-11 11:51:07 +00:00
static inline void php_session_rfc1867_early_find_sid ( php_session_rfc1867_progress * progress TSRMLS_DC ) /* { { { */
{
zval * * ppid ;
if ( PS ( use_cookies ) ) {
sapi_module . treat_data ( PARSE_COOKIE , NULL , NULL TSRMLS_CC ) ;
2009-05-18 16:09:51 +00:00
if ( PG ( http_globals ) [ TRACK_VARS_COOKIE ] & &
zend_u_hash_find ( Z_ARRVAL_P ( PG ( http_globals ) [ TRACK_VARS_COOKIE ] ) , Z_TYPE ( progress - > sname ) , Z_UNIVAL ( progress - > sname ) , Z_UNILEN ( progress - > sname ) + 1 , ( void * * ) & ppid ) = = SUCCESS
) {
2008-09-11 11:51:07 +00:00
zval_dtor ( & progress - > sid ) ;
ZVAL_ZVAL ( & progress - > sid , * ppid , 1 , 0 ) ;
convert_to_string ( & progress - > sid ) ;
progress - > apply_trans_sid = 0 ;
return ;
}
}
if ( PS ( use_only_cookies ) ) {
return ;
}
sapi_module . treat_data ( PARSE_GET , NULL , NULL TSRMLS_CC ) ;
2009-05-18 16:09:51 +00:00
if ( PG ( http_globals ) [ TRACK_VARS_GET ] & &
zend_u_hash_find ( Z_ARRVAL_P ( PG ( http_globals ) [ TRACK_VARS_GET ] ) , Z_TYPE ( progress - > sname ) , Z_UNIVAL ( progress - > sname ) , Z_UNILEN ( progress - > sname ) + 1 , ( void * * ) & ppid ) = = SUCCESS
) {
2008-09-11 11:51:07 +00:00
zval_dtor ( & progress - > sid ) ;
ZVAL_ZVAL ( & progress - > sid , * ppid , 1 , 0 ) ;
convert_to_string ( & progress - > sid ) ;
}
} /* }}} */
2008-09-27 09:08:41 +00:00
static inline void php_session_rfc1867_update ( php_session_rfc1867_progress * progress , int force_update TSRMLS_DC ) /* { { { */
2008-09-11 11:51:07 +00:00
{
2008-09-17 17:22:07 +00:00
zval * * progress_ary , * * cancel_upload ;
2008-09-27 09:08:41 +00:00
if ( ! force_update ) {
if ( Z_LVAL_P ( progress - > post_bytes_processed ) < progress - > next_update ) {
return ;
}
# ifdef HAVE_GETTIMEOFDAY
if ( PS ( rfc1867_min_freq ) > 0.0 ) {
struct timeval tv = { 0 } ;
double dtv ;
gettimeofday ( & tv , NULL ) ;
dtv = ( double ) tv . tv_sec + tv . tv_usec / 1000000.0 ;
if ( ( dtv - progress - > last_update_time ) < PS ( rfc1867_min_freq ) ) {
return ;
}
progress - > last_update_time = dtv ;
}
# endif
progress - > next_update = Z_LVAL_P ( progress - > post_bytes_processed ) + progress - > update_step ;
}
2008-09-11 11:51:07 +00:00
php_session_initialize ( TSRMLS_C ) ;
PS ( session_status ) = php_session_active ;
IF_SESSION_VARS ( ) {
2008-09-17 17:22:07 +00:00
while ( ! progress - > cancel_upload ) {
if ( zend_u_symtable_find ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , Z_TYPE ( progress - > key ) , Z_UNIVAL ( progress - > key ) , Z_UNILEN ( progress - > key ) + 1 , ( void * * ) & progress_ary ) ! = SUCCESS ) {
break ;
}
if ( Z_TYPE_PP ( progress_ary ) ! = IS_ARRAY ) {
break ;
}
if ( zend_ascii_hash_find ( Z_ARRVAL_PP ( progress_ary ) , " cancel_upload " , sizeof ( " cancel_upload " ) , ( void * * ) & cancel_upload ) ! = SUCCESS ) {
break ;
}
progress - > cancel_upload = zend_is_true ( * cancel_upload ) ;
break ;
}
2008-09-11 11:51:07 +00:00
Z_ADDREF_P ( progress - > data ) ;
zend_u_symtable_update ( Z_ARRVAL_P ( PS ( http_session_vars ) ) , Z_TYPE ( progress - > key ) , Z_UNIVAL ( progress - > key ) , Z_UNILEN ( progress - > key ) + 1 , & progress - > data , sizeof ( zval * ) , NULL ) ;
}
php_session_flush ( TSRMLS_C ) ;
} /* }}} */
static int php_session_rfc1867_callback ( unsigned int event , void * event_data , void * * extra TSRMLS_DC ) /* { { { */
{
php_session_rfc1867_progress * progress ;
int retval = SUCCESS ;
if ( php_session_rfc1867_orig_callback ) {
retval = php_session_rfc1867_orig_callback ( event , event_data , extra TSRMLS_CC ) ;
}
if ( ! PS ( rfc1867_enabled ) ) {
return retval ;
}
progress = PS ( rfc1867_progress ) ;
switch ( event ) {
case MULTIPART_EVENT_START : {
multipart_event_start * data = ( multipart_event_start * ) event_data ;
progress = ecalloc ( 1 , sizeof ( php_session_rfc1867_progress ) ) ;
progress - > content_length = data - > content_length ;
/* We need to have a runtime-encoding encoded PS(session_name) so that
* we can compare to incomming POST variables name . zvals also allow
* to keep track of length . */
ZVAL_RT_STRING ( & progress - > sname , PS ( session_name ) , ZSTR_DUPLICATE ) ;
2009-05-25 14:32:15 +00:00
ZVAL_UNICODE ( & progress - > prefix , PS ( rfc1867_prefix ) . u , 0 ) ;
ZVAL_UNICODE ( & progress - > name , PS ( rfc1867_name ) . u , 0 ) ;
2008-09-11 11:51:07 +00:00
PS ( rfc1867_progress ) = progress ;
}
break ;
case MULTIPART_EVENT_FORMDATA : {
multipart_event_formdata * data = ( multipart_event_formdata * ) event_data ;
size_t name_len , value_len ;
zstr str ;
2009-05-18 16:09:51 +00:00
2008-09-11 11:51:07 +00:00
/* orig callback may have modified *data->newlength */
if ( data - > newlength ) {
value_len = * data - > newlength ;
} else {
value_len = data - > length ;
}
/* Search PS(session_name) and PS(rfc1867_name) in incomming POST variables */
if ( data - > name . v & & data - > value & & value_len ) {
name_len = USTR_LEN ( data - > name ) ;
if ( USTR_EQUAL ( Z_UNIVAL ( progress - > sname ) , Z_UNILEN ( progress - > sname ) , data - > name , name_len ) ) {
zval_dtor ( & progress - > sid ) ;
2009-05-25 14:32:15 +00:00
ZVAL_UNICODEL ( & progress - > sid , ( * data - > value ) . u , value_len , ZSTR_DUPLICATE ) ;
2008-09-11 11:51:07 +00:00
convert_to_string ( & progress - > sid ) ;
} else if ( USTR_EQUAL ( Z_UNIVAL ( progress - > name ) , Z_UNILEN ( progress - > name ) , data - > name , name_len ) ) {
size_t len = Z_UNILEN ( progress - > prefix ) + value_len ;
str . v = emalloc ( TEXT_BYTES ( len + 1 ) ) ;
memcpy ( str . s , Z_UNIVAL ( progress - > prefix ) . v , TEXT_BYTES ( Z_UNILEN ( progress - > prefix ) ) ) ;
memcpy ( str . s + TEXT_BYTES ( Z_UNILEN ( progress - > prefix ) ) , ( * data - > value ) . v , TEXT_BYTES ( value_len + 1 ) ) ;
zval_dtor ( & progress - > key ) ;
2009-05-25 14:32:15 +00:00
ZVAL_UNICODEL ( & progress - > key , str . u , len , 0 ) ;
2008-09-11 11:51:07 +00:00
progress - > apply_trans_sid = PS ( use_trans_sid ) ;
php_session_rfc1867_early_find_sid ( progress TSRMLS_CC ) ;
}
}
}
break ;
case MULTIPART_EVENT_FILE_START : {
multipart_event_file_start * data = ( multipart_event_file_start * ) event_data ;
2009-05-18 16:09:51 +00:00
/* Do nothing when $_POST[session.upload_progress.name] is not set
2008-09-11 11:51:07 +00:00
* or when no session id was sent */
if ( ! Z_TYPE ( progress - > sid ) | | ! Z_TYPE ( progress - > key ) ) {
break ;
}
2009-05-18 16:09:51 +00:00
2008-09-11 11:51:07 +00:00
/* First FILE_START event, initializing */
if ( ! progress - > data ) {
php_rinit_session ( 0 TSRMLS_CC ) ;
PS ( id ) = estrndup ( Z_STRVAL ( progress - > sid ) , Z_STRLEN ( progress - > sid ) ) ;
PS ( apply_trans_sid ) = progress - > apply_trans_sid ;
PS ( send_cookie ) = 0 ;
if ( PS ( rfc1867_freq ) > = 0 ) {
progress - > update_step = PS ( rfc1867_freq ) ;
} else if ( PS ( rfc1867_freq ) < 0 ) { /* % of total size */
progress - > update_step = progress - > content_length * - PS ( rfc1867_freq ) / 100 ;
}
progress - > next_update = 0 ;
2008-09-27 09:08:41 +00:00
progress - > last_update_time = 0.0 ;
2008-09-11 11:51:07 +00:00
ALLOC_INIT_ZVAL ( progress - > data ) ;
array_init ( progress - > data ) ;
ALLOC_INIT_ZVAL ( progress - > post_bytes_processed ) ;
ZVAL_LONG ( progress - > post_bytes_processed , data - > post_bytes_processed ) ;
ALLOC_INIT_ZVAL ( progress - > files ) ;
array_init ( progress - > files ) ;
add_ascii_assoc_long_ex ( progress - > data , " start_time " , sizeof ( " start_time " ) , ( long ) sapi_get_request_time ( TSRMLS_C ) ) ;
add_ascii_assoc_long_ex ( progress - > data , " content_length " , sizeof ( " content_length " ) , progress - > content_length ) ;
add_ascii_assoc_zval_ex ( progress - > data , " bytes_processed " , sizeof ( " bytes_processed " ) , progress - > post_bytes_processed ) ;
add_ascii_assoc_bool_ex ( progress - > data , " done " , sizeof ( " done " ) , 0 ) ;
add_ascii_assoc_zval_ex ( progress - > data , " files " , sizeof ( " files " ) , progress - > files ) ;
}
ALLOC_INIT_ZVAL ( progress - > current_file ) ;
array_init ( progress - > current_file ) ;
ALLOC_INIT_ZVAL ( progress - > current_file_bytes_processed ) ;
ZVAL_LONG ( progress - > current_file_bytes_processed , 0 ) ;
2009-05-25 14:32:15 +00:00
add_ascii_assoc_unicode_ex ( progress - > current_file , " field_name " , sizeof ( " field_name " ) , data - > name . u , 1 ) ;
add_ascii_assoc_unicode_ex ( progress - > current_file , " name " , sizeof ( " name " ) , ( * data - > filename ) . u , 1 ) ;
2008-09-11 11:51:07 +00:00
add_ascii_assoc_null_ex ( progress - > current_file , " tmp_name " , sizeof ( " tmp_name " ) ) ;
add_ascii_assoc_long_ex ( progress - > current_file , " error " , sizeof ( " error " ) , 0 ) ;
add_ascii_assoc_long_ex ( progress - > current_file , " done " , sizeof ( " done " ) , 0 ) ;
add_ascii_assoc_long_ex ( progress - > current_file , " start_time " , sizeof ( " start_time " ) , ( long ) time ( NULL ) ) ;
add_ascii_assoc_zval_ex ( progress - > current_file , " bytes_processed " , sizeof ( " bytes_processed " ) , progress - > current_file_bytes_processed ) ;
add_next_index_zval ( progress - > files , progress - > current_file ) ;
2009-05-18 16:09:51 +00:00
2008-09-11 11:51:07 +00:00
Z_LVAL_P ( progress - > post_bytes_processed ) = data - > post_bytes_processed ;
2008-09-27 09:08:41 +00:00
php_session_rfc1867_update ( progress , 0 TSRMLS_CC ) ;
2008-09-11 11:51:07 +00:00
}
break ;
case MULTIPART_EVENT_FILE_DATA : {
multipart_event_file_data * data = ( multipart_event_file_data * ) event_data ;
if ( ! Z_TYPE ( progress - > sid ) | | ! Z_TYPE ( progress - > key ) ) {
break ;
}
2009-05-18 16:09:51 +00:00
2008-09-11 11:51:07 +00:00
Z_LVAL_P ( progress - > current_file_bytes_processed ) = data - > offset + data - > length ;
Z_LVAL_P ( progress - > post_bytes_processed ) = data - > post_bytes_processed ;
2008-09-27 09:08:41 +00:00
php_session_rfc1867_update ( progress , 0 TSRMLS_CC ) ;
2008-09-11 11:51:07 +00:00
}
break ;
case MULTIPART_EVENT_FILE_END : {
multipart_event_file_end * data = ( multipart_event_file_end * ) event_data ;
if ( ! Z_TYPE ( progress - > sid ) | | ! Z_TYPE ( progress - > key ) ) {
break ;
}
2009-05-18 16:09:51 +00:00
2008-09-11 11:51:07 +00:00
if ( data - > temp_filename . v ) {
2009-05-25 14:32:15 +00:00
add_ascii_assoc_unicode_ex ( progress - > current_file , " tmp_name " , sizeof ( " tmp_name " ) , data - > temp_filename . u , 1 ) ;
2008-09-11 11:51:07 +00:00
}
add_ascii_assoc_long_ex ( progress - > current_file , " error " , sizeof ( " error " ) , data - > cancel_upload ) ;
add_ascii_assoc_bool_ex ( progress - > current_file , " done " , sizeof ( " done " ) , 1 ) ;
Z_LVAL_P ( progress - > post_bytes_processed ) = data - > post_bytes_processed ;
2008-09-27 09:08:41 +00:00
php_session_rfc1867_update ( progress , 0 TSRMLS_CC ) ;
2008-09-11 11:51:07 +00:00
}
break ;
case MULTIPART_EVENT_END : {
multipart_event_end * data = ( multipart_event_end * ) event_data ;
if ( Z_TYPE ( progress - > sid ) & & Z_TYPE ( progress - > key ) ) {
add_ascii_assoc_bool_ex ( progress - > data , " done " , sizeof ( " done " ) , 1 ) ;
Z_LVAL_P ( progress - > post_bytes_processed ) = data - > post_bytes_processed ;
2008-09-27 09:08:41 +00:00
php_session_rfc1867_update ( progress , 1 TSRMLS_CC ) ;
2008-09-11 11:51:07 +00:00
php_rshutdown_session_globals ( TSRMLS_C ) ;
}
zval_dtor ( & progress - > sname ) ;
zval_dtor ( & progress - > sid ) ;
zval_dtor ( & progress - > key ) ;
if ( progress - > data ) {
zval_ptr_dtor ( & progress - > data ) ;
}
efree ( progress ) ;
2008-09-17 17:22:07 +00:00
progress = NULL ;
PS ( rfc1867_progress ) = NULL ;
2008-09-11 11:51:07 +00:00
}
break ;
}
2008-09-17 17:22:07 +00:00
if ( progress & & progress - > cancel_upload ) {
return FAILURE ;
}
2008-09-11 11:51:07 +00:00
return retval ;
} /* }}} */
2009-07-28 08:54:23 +00:00
static const zend_module_dep session_deps [ ] = { /* {{{ */
ZEND_MOD_OPTIONAL ( " hash " )
{ NULL , NULL , NULL }
} ;
/* }}} */
2007-01-04 22:04:38 +00:00
zend_module_entry session_module_entry = {
2009-07-28 08:54:23 +00:00
STANDARD_MODULE_HEADER_EX ,
NULL ,
session_deps ,
2007-01-04 22:04:38 +00:00
" session " ,
session_functions ,
PHP_MINIT ( session ) , PHP_MSHUTDOWN ( session ) ,
PHP_RINIT ( session ) , PHP_RSHUTDOWN ( session ) ,
PHP_MINFO ( session ) ,
NO_VERSION_YET ,
PHP_MODULE_GLOBALS ( ps ) ,
PHP_GINIT ( ps ) ,
NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES_EX
} ;
# ifdef COMPILE_DL_SESSION
ZEND_GET_MODULE ( session )
# endif
2001-06-06 14:32:27 +00:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2006-05-18 22:07:31 +00:00
* vim600 : noet sw = 4 ts = 4 fdm = marker
2001-09-09 13:29:31 +00:00
* vim < 600 : sw = 4 ts = 4
2001-06-06 14:32:27 +00:00
*/