Skip to content

Commit 84d6cb8

Browse files
authored
Unify headers already sent/session already started error handler (#16451)
* Unify headers already sent errors Now whenever we need to check where headers were already sent in ext/session, we call a single location that prints where, keeping it consistent output wise. * Unify session aready started errors Similar to the one for headers. * Also change session active checks too This usually go hand in hand with the headers already sent checks, but is in a separate commit because of the amount of tests it changes.
1 parent 39fa9cf commit 84d6cb8

20 files changed

+89
-101
lines changed

ext/session/session.c

+48-60
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ zend_class_entry *php_session_update_timestamp_iface_entry;
8383

8484
#define SESSION_CHECK_ACTIVE_STATE \
8585
if (PS(session_status) == php_session_active) { \
86-
php_error_docref(NULL, E_WARNING, "Session ini settings cannot be changed when a session is active"); \
86+
php_session_session_already_started_error(E_WARNING, "Session ini settings cannot be changed when a session is active"); \
8787
return FAILURE; \
8888
}
8989

9090
#define SESSION_CHECK_OUTPUT_STATE \
9191
if (SG(headers_sent) && stage != ZEND_INI_STAGE_DEACTIVATE) { \
92-
php_error_docref(NULL, E_WARNING, "Session ini settings cannot be changed after headers have already been sent"); \
92+
php_session_headers_already_sent_error(E_WARNING, "Session ini settings cannot be changed after headers have already been sent"); \
9393
return FAILURE; \
9494
}
9595

@@ -121,6 +121,29 @@ static inline void php_rinit_session_globals(void) /* {{{ */
121121
}
122122
/* }}} */
123123

124+
static inline void php_session_headers_already_sent_error(int severity, const char *message) { /* {{{ */
125+
const char *output_start_filename = php_output_get_start_filename();
126+
int output_start_lineno = php_output_get_start_lineno();
127+
if (output_start_filename != NULL) {
128+
php_error_docref(NULL, severity, "%s (sent from %s on line %d)", message, output_start_filename, output_start_lineno);
129+
} else {
130+
php_error_docref(NULL, severity, "%s", message);
131+
}
132+
}
133+
/* }}} */
134+
135+
static inline void php_session_session_already_started_error(int severity, const char *message) { /* {{{ */
136+
if (PS(session_started_filename) != NULL) {
137+
php_error_docref(NULL, severity, "%s (started from %s on line %"PRIu32")", message, ZSTR_VAL(PS(session_started_filename)), PS(session_started_lineno));
138+
} else if (PS(auto_start)) {
139+
/* This option can't be changed at runtime, so we can assume it's because of this */
140+
php_error_docref(NULL, severity, "%s (session started automatically)", message);
141+
} else {
142+
php_error_docref(NULL, severity, "%s", message);
143+
}
144+
}
145+
/* }}} */
146+
124147
static inline void php_session_cleanup_filename(void) /* {{{ */
125148
{
126149
if (PS(session_started_filename)) {
@@ -1327,15 +1350,8 @@ static int php_session_cache_limiter(void) /* {{{ */
13271350
if (PS(session_status) != php_session_active) return -1;
13281351

13291352
if (SG(headers_sent)) {
1330-
const char *output_start_filename = php_output_get_start_filename();
1331-
int output_start_lineno = php_output_get_start_lineno();
1332-
13331353
php_session_abort();
1334-
if (output_start_filename) {
1335-
php_error_docref(NULL, E_WARNING, "Session cache limiter cannot be sent after headers have already been sent (output started at %s:%d)", output_start_filename, output_start_lineno);
1336-
} else {
1337-
php_error_docref(NULL, E_WARNING, "Session cache limiter cannot be sent after headers have already been sent");
1338-
}
1354+
php_session_headers_already_sent_error(E_WARNING, "Session cache limiter cannot be sent after headers have already been sent");
13391355
return -2;
13401356
}
13411357

@@ -1404,14 +1420,7 @@ static zend_result php_session_send_cookie(void) /* {{{ */
14041420
zend_string *e_id;
14051421

14061422
if (SG(headers_sent)) {
1407-
const char *output_start_filename = php_output_get_start_filename();
1408-
int output_start_lineno = php_output_get_start_lineno();
1409-
1410-
if (output_start_filename) {
1411-
php_error_docref(NULL, E_WARNING, "Session cookie cannot be sent after headers have already been sent (output started at %s:%d)", output_start_filename, output_start_lineno);
1412-
} else {
1413-
php_error_docref(NULL, E_WARNING, "Session cookie cannot be sent after headers have already been sent");
1414-
}
1423+
php_session_headers_already_sent_error(E_WARNING, "Session cookie cannot be sent after headers have already been sent");
14151424
return FAILURE;
14161425
}
14171426

@@ -1606,14 +1615,7 @@ PHPAPI zend_result php_session_start(void) /* {{{ */
16061615

16071616
switch (PS(session_status)) {
16081617
case php_session_active:
1609-
if (PS(session_started_filename)) {
1610-
php_error(E_NOTICE, "Ignoring session_start() because a session has already been started (started from %s on line %"PRIu32")", ZSTR_VAL(PS(session_started_filename)), PS(session_started_lineno));
1611-
} else if (PS(auto_start)) {
1612-
/* This option can't be changed at runtime, so we can assume it's because of this */
1613-
php_error(E_NOTICE, "Ignoring session_start() because a session has already been started automatically");
1614-
} else {
1615-
php_error(E_NOTICE, "Ignoring session_start() because a session has already been started");
1616-
}
1618+
php_session_session_already_started_error(E_NOTICE, "Ignoring session_start() because a session has already been started");
16171619
return FAILURE;
16181620
break;
16191621

@@ -1796,12 +1798,12 @@ PHP_FUNCTION(session_set_cookie_params)
17961798
}
17971799

17981800
if (PS(session_status) == php_session_active) {
1799-
php_error_docref(NULL, E_WARNING, "Session cookie parameters cannot be changed when a session is active");
1801+
php_session_session_already_started_error(E_WARNING, "Session cookie parameters cannot be changed when a session is active");
18001802
RETURN_FALSE;
18011803
}
18021804

18031805
if (SG(headers_sent)) {
1804-
php_error_docref(NULL, E_WARNING, "Session cookie parameters cannot be changed after headers have already been sent");
1806+
php_session_headers_already_sent_error(E_WARNING, "Session cookie parameters cannot be changed after headers have already been sent");
18051807
RETURN_FALSE;
18061808
}
18071809

@@ -1968,12 +1970,12 @@ PHP_FUNCTION(session_name)
19681970
}
19691971

19701972
if (name && PS(session_status) == php_session_active) {
1971-
php_error_docref(NULL, E_WARNING, "Session name cannot be changed when a session is active");
1973+
php_session_session_already_started_error(E_WARNING, "Session name cannot be changed when a session is active");
19721974
RETURN_FALSE;
19731975
}
19741976

19751977
if (name && SG(headers_sent)) {
1976-
php_error_docref(NULL, E_WARNING, "Session name cannot be changed after headers have already been sent");
1978+
php_session_headers_already_sent_error(E_WARNING, "Session name cannot be changed after headers have already been sent");
19771979
RETURN_FALSE;
19781980
}
19791981

@@ -1998,12 +2000,12 @@ PHP_FUNCTION(session_module_name)
19982000
}
19992001

20002002
if (name && PS(session_status) == php_session_active) {
2001-
php_error_docref(NULL, E_WARNING, "Session save handler module cannot be changed when a session is active");
2003+
php_session_session_already_started_error(E_WARNING, "Session save handler module cannot be changed when a session is active");
20022004
RETURN_FALSE;
20032005
}
20042006

20052007
if (name && SG(headers_sent)) {
2006-
php_error_docref(NULL, E_WARNING, "Session save handler module cannot be changed after headers have already been sent");
2008+
php_session_headers_already_sent_error(E_WARNING, "Session save handler module cannot be changed after headers have already been sent");
20072009
RETURN_FALSE;
20082010
}
20092011

@@ -2039,12 +2041,12 @@ PHP_FUNCTION(session_module_name)
20392041

20402042
static bool can_session_handler_be_changed(void) {
20412043
if (PS(session_status) == php_session_active) {
2042-
php_error_docref(NULL, E_WARNING, "Session save handler cannot be changed when a session is active");
2044+
php_session_session_already_started_error(E_WARNING, "Session save handler cannot be changed when a session is active");
20432045
return false;
20442046
}
20452047

20462048
if (SG(headers_sent)) {
2047-
php_error_docref(NULL, E_WARNING, "Session save handler cannot be changed after headers have already been sent");
2049+
php_session_headers_already_sent_error(E_WARNING, "Session save handler cannot be changed after headers have already been sent");
20482050
return false;
20492051
}
20502052

@@ -2279,12 +2281,12 @@ PHP_FUNCTION(session_save_path)
22792281
}
22802282

22812283
if (name && PS(session_status) == php_session_active) {
2282-
php_error_docref(NULL, E_WARNING, "Session save path cannot be changed when a session is active");
2284+
php_session_session_already_started_error(E_WARNING, "Session save path cannot be changed when a session is active");
22832285
RETURN_FALSE;
22842286
}
22852287

22862288
if (name && SG(headers_sent)) {
2287-
php_error_docref(NULL, E_WARNING, "Session save path cannot be changed after headers have already been sent");
2289+
php_session_headers_already_sent_error(E_WARNING, "Session save path cannot be changed after headers have already been sent");
22882290
RETURN_FALSE;
22892291
}
22902292

@@ -2308,12 +2310,12 @@ PHP_FUNCTION(session_id)
23082310
}
23092311

23102312
if (name && PS(session_status) == php_session_active) {
2311-
php_error_docref(NULL, E_WARNING, "Session ID cannot be changed when a session is active");
2313+
php_session_session_already_started_error(E_WARNING, "Session ID cannot be changed when a session is active");
23122314
RETURN_FALSE;
23132315
}
23142316

23152317
if (name && PS(use_cookies) && SG(headers_sent)) {
2316-
php_error_docref(NULL, E_WARNING, "Session ID cannot be changed after headers have already been sent");
2318+
php_session_headers_already_sent_error(E_WARNING, "Session ID cannot be changed after headers have already been sent");
23172319
RETURN_FALSE;
23182320
}
23192321

@@ -2350,12 +2352,12 @@ PHP_FUNCTION(session_regenerate_id)
23502352
}
23512353

23522354
if (PS(session_status) != php_session_active) {
2353-
php_error_docref(NULL, E_WARNING, "Session ID cannot be regenerated when there is no active session");
2355+
php_session_session_already_started_error(E_WARNING, "Session ID cannot be regenerated when there is no active session");
23542356
RETURN_FALSE;
23552357
}
23562358

23572359
if (SG(headers_sent)) {
2358-
php_error_docref(NULL, E_WARNING, "Session ID cannot be regenerated after headers have already been sent");
2360+
php_session_headers_already_sent_error(E_WARNING, "Session ID cannot be regenerated after headers have already been sent");
23592361
RETURN_FALSE;
23602362
}
23612363

@@ -2521,12 +2523,12 @@ PHP_FUNCTION(session_cache_limiter)
25212523
}
25222524

25232525
if (limiter && PS(session_status) == php_session_active) {
2524-
php_error_docref(NULL, E_WARNING, "Session cache limiter cannot be changed when a session is active");
2526+
php_session_session_already_started_error(E_WARNING, "Session cache limiter cannot be changed when a session is active");
25252527
RETURN_FALSE;
25262528
}
25272529

25282530
if (limiter && SG(headers_sent)) {
2529-
php_error_docref(NULL, E_WARNING, "Session cache limiter cannot be changed after headers have already been sent");
2531+
php_session_headers_already_sent_error(E_WARNING, "Session cache limiter cannot be changed after headers have already been sent");
25302532
RETURN_FALSE;
25312533
}
25322534

@@ -2551,12 +2553,12 @@ PHP_FUNCTION(session_cache_expire)
25512553
}
25522554

25532555
if (!expires_is_null && PS(session_status) == php_session_active) {
2554-
php_error_docref(NULL, E_WARNING, "Session cache expiration cannot be changed when a session is active");
2556+
php_session_session_already_started_error(E_WARNING, "Session cache expiration cannot be changed when a session is active");
25552557
RETURN_LONG(PS(cache_expire));
25562558
}
25572559

25582560
if (!expires_is_null && SG(headers_sent)) {
2559-
php_error_docref(NULL, E_WARNING, "Session cache expiration cannot be changed after headers have already been sent");
2561+
php_session_headers_already_sent_error(E_WARNING, "Session cache expiration cannot be changed after headers have already been sent");
25602562
RETURN_FALSE;
25612563
}
25622564

@@ -2637,14 +2639,7 @@ PHP_FUNCTION(session_start)
26372639
}
26382640

26392641
if (PS(session_status) == php_session_active) {
2640-
if (PS(session_started_filename)) {
2641-
php_error_docref(NULL, E_NOTICE, "Ignoring session_start() because a session is already active (started from %s on line %"PRIu32")", ZSTR_VAL(PS(session_started_filename)), PS(session_started_lineno));
2642-
} else if (PS(auto_start)) {
2643-
/* This option can't be changed at runtime, so we can assume it's because of this */
2644-
php_error_docref(NULL, E_NOTICE, "Ignoring session_start() because a session is already automatically active");
2645-
} else {
2646-
php_error_docref(NULL, E_NOTICE, "Ignoring session_start() because a session is already active");
2647-
}
2642+
php_session_session_already_started_error(E_NOTICE, "Ignoring session_start() because a session is already active");
26482643
RETURN_TRUE;
26492644
}
26502645

@@ -2654,14 +2649,7 @@ PHP_FUNCTION(session_start)
26542649
* module is unable to rewrite output.
26552650
*/
26562651
if (PS(use_cookies) && SG(headers_sent)) {
2657-
/* It's the header sent to blame, not the session in this case */
2658-
const char *output_start_filename = php_output_get_start_filename();
2659-
int output_start_lineno = php_output_get_start_lineno();
2660-
if (output_start_filename != NULL) {
2661-
php_error_docref(NULL, E_WARNING, "Session cannot be started after headers have already been sent (sent from %s on line %d)", output_start_filename, output_start_lineno);
2662-
} else {
2663-
php_error_docref(NULL, E_WARNING, "Session cannot be started after headers have already been sent");
2664-
}
2652+
php_session_headers_already_sent_error(E_WARNING, "Session cannot be started after headers have already been sent");
26652653
RETURN_FALSE;
26662654
}
26672655

ext/session/tests/014.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ session_destroy();
3535
--EXPECTF--
3636
<a href="/link">
3737

38-
Warning: ini_set(): Session ini settings cannot be changed when a session is active in %s on line %d
38+
Warning: ini_set(): Session ini settings cannot be changed when a session is active (started from %s on line %d) in %s on line %d
3939
<a href="/link">
4040

41-
Warning: ini_set(): Session ini settings cannot be changed when a session is active in %s on line %d
41+
Warning: ini_set(): Session ini settings cannot be changed when a session is active (started from %s on line %d) in %s on line %d
4242
<a href="/link">

ext/session/tests/bug73100.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ try {
2222
--EXPECTF--
2323
bool(true)
2424

25-
Warning: session_module_name(): Session save handler module cannot be changed when a session is active in %s on line %d
25+
Warning: session_module_name(): Session save handler module cannot be changed when a session is active (started from %s on line %d) in %s on line %d
2626
bool(true)
2727
session_module_name(): Argument #1 ($module) cannot be "user"
2828
===DONE===

ext/session/tests/session_cache_limiter_variation1.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ string(7) "nocache"
3030
bool(true)
3131
string(7) "nocache"
3232

33-
Warning: session_cache_limiter(): Session cache limiter cannot be changed when a session is active in %s on line %d
33+
Warning: session_cache_limiter(): Session cache limiter cannot be changed when a session is active (started from %s on line %d) in %s on line %d
3434
bool(false)
3535
string(7) "nocache"
3636
bool(true)

ext/session/tests/session_cache_limiter_variation2.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ string(7) "nocache"
2929
bool(true)
3030
string(7) "nocache"
3131

32-
Warning: session_cache_limiter(): Session cache limiter cannot be changed when a session is active in %s on line %d
32+
Warning: session_cache_limiter(): Session cache limiter cannot be changed when a session is active (started from %s on line %d) in %s on line %d
3333
bool(false)
3434
string(7) "nocache"
3535
bool(true)

ext/session/tests/session_cache_limiter_variation3.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ string(7) "nocache"
2828
bool(true)
2929
string(7) "nocache"
3030

31-
Warning: session_cache_limiter(): Session cache limiter cannot be changed when a session is active in %s on line %d
31+
Warning: session_cache_limiter(): Session cache limiter cannot be changed when a session is active (started from %s on line %d) in %s on line %d
3232
bool(false)
3333
string(7) "nocache"
3434
bool(true)

ext/session/tests/session_id_error2.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ string(4) "test"
3131
string(10) "1234567890"
3232
bool(true)
3333

34-
Warning: session_id(): Session ID cannot be changed when a session is active in %s on line %d
34+
Warning: session_id(): Session ID cannot be changed when a session is active (started from %s on line %d) in %s on line %d
3535
bool(false)
3636
bool(true)
3737
string(0) ""

0 commit comments

Comments
 (0)