@@ -61,40 +61,9 @@ typedef struct {
6161} ps_files ;
6262
6363ps_module ps_mod_files = {
64- PS_MOD (files )
64+ PS_MOD_SID (files )
6565};
6666
67- /* If you change the logic here, please also update the error message in
68- * ps_files_open() appropriately */
69- static int ps_files_valid_key (const char * key )
70- {
71- size_t len ;
72- const char * p ;
73- char c ;
74- int ret = 1 ;
75-
76- for (p = key ; (c = * p ); p ++ ) {
77- /* valid characters are a..z,A..Z,0..9 */
78- if (!((c >= 'a' && c <= 'z' )
79- || (c >= 'A' && c <= 'Z' )
80- || (c >= '0' && c <= '9' )
81- || c == ','
82- || c == '-' )) {
83- ret = 0 ;
84- break ;
85- }
86- }
87-
88- len = p - key ;
89-
90- /* Somewhat arbitrary length limit here, but should be way more than
91- anyone needs and avoids file-level warnings later on if we exceed MAX_PATH */
92- if (len == 0 || len > 128 ) {
93- ret = 0 ;
94- }
95-
96- return ret ;
97- }
9867
9968static char * ps_files_path_create (char * buf , size_t buflen , ps_files * data , const char * key )
10069{
@@ -155,11 +124,11 @@ static void ps_files_open(ps_files *data, const char *key TSRMLS_DC)
155124
156125 ps_files_close (data );
157126
158- if (! ps_files_valid_key (key )) {
127+ if (php_session_valid_key (key ) == FAILURE ) {
159128 php_error_docref (NULL TSRMLS_CC , E_WARNING , "The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'" );
160- PS (invalid_session_id ) = 1 ;
161129 return ;
162130 }
131+
163132 if (!ps_files_path_create (buf , sizeof (buf ), data , key )) {
164133 return ;
165134 }
@@ -253,6 +222,21 @@ static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC)
253222 return (nrdels );
254223}
255224
225+ static int ps_files_key_exists (ps_files * data , const char * key TSRMLS_DC )
226+ {
227+ char buf [MAXPATHLEN ];
228+ struct stat sbuf ;
229+
230+ if (!key || !ps_files_path_create (buf , sizeof (buf ), data , key )) {
231+ return FAILURE ;
232+ }
233+ if (VCWD_STAT (buf , & sbuf )) {
234+ return FAILURE ;
235+ }
236+ return SUCCESS ;
237+ }
238+
239+
256240#define PS_FILES_DATA ps_files *data = PS_GET_MOD_DATA()
257241
258242PS_OPEN_FUNC (files )
@@ -342,6 +326,24 @@ PS_READ_FUNC(files)
342326 struct stat sbuf ;
343327 PS_FILES_DATA ;
344328
329+ /* If strict mode, check session id existence */
330+ if (PS (use_strict_mode ) &&
331+ ps_files_key_exists (data , key TSRMLS_CC ) == FAILURE ) {
332+ /* key points to PS(id), but cannot change here. */
333+ if (key ) {
334+ efree (PS (id ));
335+ PS (id ) = NULL ;
336+ }
337+ PS (id ) = PS (mod )-> s_create_sid ((void * * )& data , NULL TSRMLS_CC );
338+ if (!PS (id )) {
339+ return FAILURE ;
340+ }
341+ php_session_reset_id (TSRMLS_C );
342+ if (PS (use_cookies )) {
343+ PS (send_cookie ) = 1 ;
344+ }
345+ }
346+
345347 ps_files_open (data , key TSRMLS_CC );
346348 if (data -> fd < 0 ) {
347349 return FAILURE ;
@@ -454,6 +456,30 @@ PS_GC_FUNC(files)
454456 return SUCCESS ;
455457}
456458
459+ PS_CREATE_SID_FUNC (files )
460+ {
461+ char * sid ;
462+ int maxfail = 3 ;
463+ PS_FILES_DATA ;
464+
465+ do {
466+ sid = php_session_create_id ((void * * )& data , newlen TSRMLS_CC );
467+ /* Check collision */
468+ if (data && ps_files_key_exists (data , sid TSRMLS_CC ) == SUCCESS ) {
469+ if (sid ) {
470+ efree (sid );
471+ sid = NULL ;
472+ }
473+ if (!(maxfail -- )) {
474+ return NULL ;
475+ }
476+ }
477+ } while (!sid );
478+
479+ return sid ;
480+ }
481+
482+
457483/*
458484 * Local variables:
459485 * tab-width: 4
0 commit comments