@@ -102,6 +102,7 @@ zend_class_entry *php_session_update_timestamp_iface_entry;
102
102
103
103
static zend_result php_session_send_cookie (void );
104
104
static zend_result php_session_abort (void );
105
+ static void ppid2sid (zval * proposed_session_id );
105
106
106
107
/* Initialized in MINIT, readonly otherwise. */
107
108
static int my_module_number = 0 ;
@@ -369,7 +370,7 @@ PHPAPI zend_string *php_session_create_id(PS_CREATE_SID_ARGS)
369
370
* ps_modules appropriately */
370
371
PHPAPI zend_result php_session_valid_key (const char * key )
371
372
{
372
- size_t len ;
373
+ size_t key_len ;
373
374
const char * p ;
374
375
char c ;
375
376
@@ -384,11 +385,11 @@ PHPAPI zend_result php_session_valid_key(const char *key)
384
385
}
385
386
}
386
387
387
- len = p - key ;
388
+ key_len = p - key ;
388
389
389
390
/* Somewhat arbitrary length limit here, but should be way more than
390
391
anyone needs and avoids file-level warnings later on if we exceed MAX_PATH */
391
- if (len == 0 || len > PS_MAX_SID_LENGTH ) {
392
+ if (key_len == 0 || key_len > PS_MAX_SID_LENGTH ) {
392
393
return FAILURE ;
393
394
}
394
395
@@ -398,20 +399,21 @@ PHPAPI zend_result php_session_valid_key(const char *key)
398
399
399
400
static zend_long php_session_gc (bool immediate )
400
401
{
401
- zend_long num = -1 ;
402
+ zend_long sessions_deleted = -1 ;
402
403
bool collect = immediate ;
403
404
404
405
/* GC must be done before reading session data. */
405
406
if ((PS (mod_data ) || PS (mod_user_implemented ))) {
407
+ /* Use probability-based GC if not forced and probability is configured */
406
408
if (!collect && PS (gc_probability ) > 0 ) {
407
409
collect = php_random_range (PS (random ), 0 , PS (gc_divisor ) - 1 ) < PS (gc_probability );
408
410
}
409
411
410
412
if (collect ) {
411
- PS (mod )-> s_gc (& PS (mod_data ), PS (gc_maxlifetime ), & num );
413
+ PS (mod )-> s_gc (& PS (mod_data ), PS (gc_maxlifetime ), & sessions_deleted );
412
414
}
413
415
}
414
- return num ;
416
+ return sessions_deleted ;
415
417
}
416
418
417
419
static zend_result php_session_initialize (void )
@@ -1441,37 +1443,132 @@ static zend_result php_session_send_cookie(void)
1441
1443
1442
1444
PHPAPI const ps_module * _php_find_ps_module (const char * name )
1443
1445
{
1444
- const ps_module * ret = NULL ;
1445
- const ps_module * * mod ;
1446
- int i ;
1446
+ const ps_module * found_module = NULL ;
1447
+ const ps_module * * current_module ;
1448
+ int module_index ;
1447
1449
1448
- for (i = 0 , mod = ps_modules ; i < MAX_MODULES ; i ++ , mod ++ ) {
1449
- if (* mod && !strcasecmp (name , (* mod )-> s_name )) {
1450
- ret = * mod ;
1450
+ for (module_index = 0 , current_module = ps_modules ; module_index < MAX_MODULES ; module_index ++ , current_module ++ ) {
1451
+ if (* current_module && !strcasecmp (name , (* current_module )-> s_name )) {
1452
+ found_module = * current_module ;
1451
1453
break ;
1452
1454
}
1453
1455
}
1454
- return ret ;
1456
+ return found_module ;
1455
1457
}
1456
1458
1457
1459
PHPAPI const ps_serializer * _php_find_ps_serializer (const char * name )
1458
1460
{
1459
- const ps_serializer * ret = NULL ;
1460
- const ps_serializer * mod ;
1461
+ const ps_serializer * found_serializer = NULL ;
1462
+ const ps_serializer * current_serializer ;
1461
1463
1462
- for (mod = ps_serializers ; mod -> name ; mod ++ ) {
1463
- if (!strcasecmp (name , mod -> name )) {
1464
- ret = mod ;
1464
+ for (current_serializer = ps_serializers ; current_serializer -> name ; current_serializer ++ ) {
1465
+ if (!strcasecmp (name , current_serializer -> name )) {
1466
+ found_serializer = current_serializer ;
1465
1467
break ;
1466
1468
}
1467
1469
}
1468
- return ret ;
1470
+ return found_serializer ;
1471
+ }
1472
+
1473
+ static bool should_invalidate_session_for_external_referer (void )
1474
+ {
1475
+ zval * referer_data ;
1476
+
1477
+ /* No external referer check configured */
1478
+ if (!PS (id ) || PS (extern_referer_chk )[0 ] == '\0' ) {
1479
+ return false;
1480
+ }
1481
+
1482
+ /* No SERVER globals available */
1483
+ if (Z_ISUNDEF (PG (http_globals )[TRACK_VARS_SERVER ])) {
1484
+ return false;
1485
+ }
1486
+
1487
+ /* Get HTTP_REFERER header */
1488
+ referer_data = zend_hash_str_find (Z_ARRVAL (PG (http_globals )[TRACK_VARS_SERVER ]), ZEND_STRL ("HTTP_REFERER" ));
1489
+ if (!referer_data || Z_TYPE_P (referer_data ) != IS_STRING || Z_STRLEN_P (referer_data ) == 0 ) {
1490
+ return false;
1491
+ }
1492
+
1493
+ /* Check if referer contains expected string */
1494
+ return strstr (Z_STRVAL_P (referer_data ), PS (extern_referer_chk )) == NULL ;
1495
+ }
1496
+
1497
+ static void try_find_session_id_in_global (const char * global_name )
1498
+ {
1499
+ zval * global_data , * potential_session_id ;
1500
+
1501
+ if (PS (id )) {
1502
+ return ;
1503
+ }
1504
+
1505
+ global_data = zend_hash_str_find (& EG (symbol_table ), global_name , strlen (global_name ));
1506
+ if (!global_data ) {
1507
+ return ;
1508
+ }
1509
+
1510
+ ZVAL_DEREF (global_data );
1511
+ if (Z_TYPE_P (global_data ) != IS_ARRAY ) {
1512
+ return ;
1513
+ }
1514
+
1515
+ potential_session_id = zend_hash_find (Z_ARRVAL_P (global_data ), PS (session_name ));
1516
+ if (potential_session_id ) {
1517
+ ppid2sid (potential_session_id );
1518
+ }
1519
+ }
1520
+
1521
+ static bool can_change_session_setting (const char * setting_name , bool check_cookies )
1522
+ {
1523
+ if (PS (session_status ) == php_session_active ) {
1524
+ char error_msg [256 ];
1525
+ snprintf (error_msg , sizeof (error_msg ), "Session %s cannot be changed when a session is active" , setting_name );
1526
+ php_session_session_already_started_error (E_WARNING , error_msg );
1527
+
1528
+ return false;
1529
+ }
1530
+
1531
+ if (SG (headers_sent ) && (!check_cookies || PS (use_cookies ))) {
1532
+ char error_msg [256 ];
1533
+ snprintf (error_msg , sizeof (error_msg ), "Session %s cannot be changed after headers have already been sent" , setting_name );
1534
+ php_session_headers_already_sent_error (E_WARNING , error_msg );
1535
+
1536
+ return false;
1537
+ }
1538
+
1539
+ return true;
1540
+ }
1541
+
1542
+ static void try_find_session_id_in_cookies (void )
1543
+ {
1544
+ zval * cookie_data , * potential_session_id ;
1545
+
1546
+ if (!PS (use_cookies ) || PS (id )) {
1547
+ return ;
1548
+ }
1549
+
1550
+ cookie_data = zend_hash_str_find (& EG (symbol_table ), ZEND_STRL ("_COOKIE" ));
1551
+ if (!cookie_data ) {
1552
+ return ;
1553
+ }
1554
+
1555
+ ZVAL_DEREF (cookie_data );
1556
+ if (Z_TYPE_P (cookie_data ) != IS_ARRAY ) {
1557
+ return ;
1558
+ }
1559
+
1560
+ potential_session_id = zend_hash_find (Z_ARRVAL_P (cookie_data ), PS (session_name ));
1561
+ if (potential_session_id ) {
1562
+ ppid2sid (potential_session_id );
1563
+ PS (send_cookie ) = 0 ;
1564
+ PS (define_sid ) = 0 ;
1565
+ }
1469
1566
}
1470
1567
1471
- static void ppid2sid (zval * ppid ) {
1472
- ZVAL_DEREF (ppid );
1473
- if (Z_TYPE_P (ppid ) == IS_STRING ) {
1474
- PS (id ) = zend_string_copy (Z_STR_P (ppid ));
1568
+ static void ppid2sid (zval * proposed_session_id ) {
1569
+ ZVAL_DEREF (proposed_session_id );
1570
+ if (Z_TYPE_P (proposed_session_id ) == IS_STRING ) {
1571
+ PS (id ) = zend_string_copy (Z_STR_P (proposed_session_id ));
1475
1572
PS (send_cookie ) = 0 ;
1476
1573
} else {
1477
1574
PS (id ) = NULL ;
@@ -1561,8 +1658,6 @@ PHPAPI zend_result php_session_reset_id(void)
1561
1658
1562
1659
PHPAPI zend_result php_session_start (void )
1563
1660
{
1564
- zval * ppid ;
1565
- zval * data ;
1566
1661
char * value ;
1567
1662
1568
1663
switch (PS (session_status )) {
@@ -1607,37 +1702,13 @@ PHPAPI zend_result php_session_start(void)
1607
1702
*/
1608
1703
1609
1704
if (!PS (id )) {
1610
- if (PS (use_cookies ) && (data = zend_hash_str_find (& EG (symbol_table ), ZEND_STRL ("_COOKIE" )))) {
1611
- ZVAL_DEREF (data );
1612
- if (Z_TYPE_P (data ) == IS_ARRAY && (ppid = zend_hash_find (Z_ARRVAL_P (data ), PS (session_name )))) {
1613
- ppid2sid (ppid );
1614
- PS (send_cookie ) = 0 ;
1615
- PS (define_sid ) = 0 ;
1616
- }
1617
- }
1618
- /* Initialize session ID from non cookie values */
1705
+ try_find_session_id_in_cookies ();
1706
+
1619
1707
if (!PS (use_only_cookies )) {
1620
- if (!PS (id ) && (data = zend_hash_str_find (& EG (symbol_table ), ZEND_STRL ("_GET" )))) {
1621
- ZVAL_DEREF (data );
1622
- if (Z_TYPE_P (data ) == IS_ARRAY && (ppid = zend_hash_find (Z_ARRVAL_P (data ), PS (session_name )))) {
1623
- ppid2sid (ppid );
1624
- }
1625
- }
1626
- if (!PS (id ) && (data = zend_hash_str_find (& EG (symbol_table ), ZEND_STRL ("_POST" )))) {
1627
- ZVAL_DEREF (data );
1628
- if (Z_TYPE_P (data ) == IS_ARRAY && (ppid = zend_hash_find (Z_ARRVAL_P (data ), PS (session_name )))) {
1629
- ppid2sid (ppid );
1630
- }
1631
- }
1632
- /* Check whether the current request was referred to by
1633
- * an external site which invalidates the previously found id. */
1634
- if (PS (id ) && PS (extern_referer_chk )[0 ] != '\0' &&
1635
- !Z_ISUNDEF (PG (http_globals )[TRACK_VARS_SERVER ]) &&
1636
- (data = zend_hash_str_find (Z_ARRVAL (PG (http_globals )[TRACK_VARS_SERVER ]), ZEND_STRL ("HTTP_REFERER" ))) &&
1637
- Z_TYPE_P (data ) == IS_STRING &&
1638
- Z_STRLEN_P (data ) != 0 &&
1639
- strstr (Z_STRVAL_P (data ), PS (extern_referer_chk )) == NULL
1640
- ) {
1708
+ try_find_session_id_in_global ("_GET" );
1709
+ try_find_session_id_in_global ("_POST" );
1710
+
1711
+ if (should_invalidate_session_for_external_referer ()) {
1641
1712
zend_string_release_ex (PS (id ), 0 );
1642
1713
PS (id ) = NULL ;
1643
1714
}
@@ -1923,13 +1994,7 @@ PHP_FUNCTION(session_name)
1923
1994
RETURN_THROWS ();
1924
1995
}
1925
1996
1926
- if (name && PS (session_status ) == php_session_active ) {
1927
- php_session_session_already_started_error (E_WARNING , "Session name cannot be changed when a session is active" );
1928
- RETURN_FALSE ;
1929
- }
1930
-
1931
- if (name && SG (headers_sent )) {
1932
- php_session_headers_already_sent_error (E_WARNING , "Session name cannot be changed after headers have already been sent" );
1997
+ if (name && !can_change_session_setting ("name" , false)) {
1933
1998
RETURN_FALSE ;
1934
1999
}
1935
2000
@@ -1952,13 +2017,7 @@ PHP_FUNCTION(session_module_name)
1952
2017
RETURN_THROWS ();
1953
2018
}
1954
2019
1955
- if (name && PS (session_status ) == php_session_active ) {
1956
- php_session_session_already_started_error (E_WARNING , "Session save handler module cannot be changed when a session is active" );
1957
- RETURN_FALSE ;
1958
- }
1959
-
1960
- if (name && SG (headers_sent )) {
1961
- php_session_headers_already_sent_error (E_WARNING , "Session save handler module cannot be changed after headers have already been sent" );
2020
+ if (name && !can_change_session_setting ("save handler module" , false)) {
1962
2021
RETURN_FALSE ;
1963
2022
}
1964
2023
@@ -2227,13 +2286,7 @@ PHP_FUNCTION(session_save_path)
2227
2286
RETURN_THROWS ();
2228
2287
}
2229
2288
2230
- if (name && PS (session_status ) == php_session_active ) {
2231
- php_session_session_already_started_error (E_WARNING , "Session save path cannot be changed when a session is active" );
2232
- RETURN_FALSE ;
2233
- }
2234
-
2235
- if (name && SG (headers_sent )) {
2236
- php_session_headers_already_sent_error (E_WARNING , "Session save path cannot be changed after headers have already been sent" );
2289
+ if (name && !can_change_session_setting ("save path" , false)) {
2237
2290
RETURN_FALSE ;
2238
2291
}
2239
2292
@@ -2255,13 +2308,7 @@ PHP_FUNCTION(session_id)
2255
2308
RETURN_THROWS ();
2256
2309
}
2257
2310
2258
- if (name && PS (session_status ) == php_session_active ) {
2259
- php_session_session_already_started_error (E_WARNING , "Session ID cannot be changed when a session is active" );
2260
- RETURN_FALSE ;
2261
- }
2262
-
2263
- if (name && PS (use_cookies ) && SG (headers_sent )) {
2264
- php_session_headers_already_sent_error (E_WARNING , "Session ID cannot be changed after headers have already been sent" );
2311
+ if (name && !can_change_session_setting ("ID" , true)) {
2265
2312
RETURN_FALSE ;
2266
2313
}
2267
2314
@@ -2962,24 +3009,24 @@ static PHP_MSHUTDOWN_FUNCTION(session)
2962
3009
2963
3010
static PHP_MINFO_FUNCTION (session )
2964
3011
{
2965
- const ps_module * * mod ;
2966
- ps_serializer * ser ;
3012
+ const ps_module * * current_save_handler ;
3013
+ ps_serializer * current_serializer ;
2967
3014
smart_str save_handlers = {0 };
2968
3015
smart_str ser_handlers = {0 };
2969
- int i ;
3016
+ int handler_index ;
2970
3017
2971
- /* Get save handlers */
2972
- for (i = 0 , mod = ps_modules ; i < MAX_MODULES ; i ++ , mod ++ ) {
2973
- if (* mod && (* mod )-> s_name ) {
2974
- smart_str_appends (& save_handlers , (* mod )-> s_name );
3018
+ /* Collect names of all available save handlers */
3019
+ for (handler_index = 0 , current_save_handler = ps_modules ; handler_index < MAX_MODULES ; handler_index ++ , current_save_handler ++ ) {
3020
+ if (* current_save_handler && (* current_save_handler )-> s_name ) {
3021
+ smart_str_appends (& save_handlers , (* current_save_handler )-> s_name );
2975
3022
smart_str_appendc (& save_handlers , ' ' );
2976
3023
}
2977
3024
}
2978
3025
2979
- /* Get serializer handlers */
2980
- for (i = 0 , ser = ps_serializers ; i < MAX_SERIALIZERS ; i ++ , ser ++ ) {
2981
- if (ser -> name ) {
2982
- smart_str_appends (& ser_handlers , ser -> name );
3026
+ /* Collect names of all available serializers */
3027
+ for (handler_index = 0 , current_serializer = ps_serializers ; handler_index < MAX_SERIALIZERS ; handler_index ++ , current_serializer ++ ) {
3028
+ if (current_serializer -> name ) {
3029
+ smart_str_appends (& ser_handlers , current_serializer -> name );
2983
3030
smart_str_appendc (& ser_handlers , ' ' );
2984
3031
}
2985
3032
}
@@ -3019,16 +3066,16 @@ static const zend_module_dep session_deps[] = {
3019
3066
3020
3067
static bool early_find_sid_in (zval * dest , int where , php_session_rfc1867_progress * progress )
3021
3068
{
3022
- zval * ppid ;
3069
+ zval * potential_session_id ;
3023
3070
3024
3071
if (Z_ISUNDEF (PG (http_globals )[where ])) {
3025
3072
return 0 ;
3026
3073
}
3027
3074
3028
- if ((ppid = zend_hash_find (Z_ARRVAL (PG (http_globals )[where ]), PS (session_name )))
3029
- && Z_TYPE_P (ppid ) == IS_STRING ) {
3075
+ if ((potential_session_id = zend_hash_find (Z_ARRVAL (PG (http_globals )[where ]), PS (session_name )))
3076
+ && Z_TYPE_P (potential_session_id ) == IS_STRING ) {
3030
3077
zval_ptr_dtor (dest );
3031
- ZVAL_COPY_DEREF (dest , ppid );
3078
+ ZVAL_COPY_DEREF (dest , potential_session_id );
3032
3079
return 1 ;
3033
3080
}
3034
3081
0 commit comments