Skip to content

Commit 97202d9

Browse files
committed
Make sure output start filename is not freed early
As filenames are no longer interned, we need to keep a reference to the zend_string to make sure it isn't freed. To avoid a nominal source compatibility break, create a new member in the globals.
1 parent 28e21d8 commit 97202d9

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Output start at eval()
3+
--FILE--
4+
<?php
5+
eval('echo "Foo\n";');
6+
header('Foo: Bar');
7+
?>
8+
--EXPECTF--
9+
Foo
10+
11+
Warning: Cannot modify header information - headers already sent by (output started at %s(2) : eval()'d code:1) in %s on line %d

main/output.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,20 @@ static size_t (*php_output_direct)(const char *str, size_t str_len) = php_output
103103
static void php_output_header(void)
104104
{
105105
if (!SG(headers_sent)) {
106-
if (!OG(output_start_filename)) {
106+
if (!OG(output_start_filename_str)) {
107107
if (zend_is_compiling()) {
108-
OG(output_start_filename) = ZSTR_VAL(zend_get_compiled_filename());
108+
OG(output_start_filename_str) = zend_get_compiled_filename();
109109
OG(output_start_lineno) = zend_get_compiled_lineno();
110110
} else if (zend_is_executing()) {
111-
OG(output_start_filename) = zend_get_executed_filename();
111+
OG(output_start_filename_str) = zend_get_executed_filename_ex();
112112
OG(output_start_lineno) = zend_get_executed_lineno();
113113
}
114+
if (OG(output_start_filename_str)) {
115+
zend_string_addref(OG(output_start_filename_str));
116+
}
114117
#if PHP_OUTPUT_DEBUG
115-
fprintf(stderr, "!!! output started at: %s (%d)\n", OG(output_start_filename), OG(output_start_lineno));
118+
fprintf(stderr, "!!! output started at: %s (%d)\n",
119+
ZSTR_VAL(OG(output_start_filename_str)), OG(output_start_lineno));
116120
#endif
117121
}
118122
if (!php_header()) {
@@ -190,6 +194,11 @@ PHPAPI void php_output_deactivate(void)
190194
}
191195
zend_stack_destroy(&OG(handlers));
192196
}
197+
198+
if (OG(output_start_filename_str)) {
199+
zend_string_release(OG(output_start_filename_str));
200+
OG(output_start_filename_str) = NULL;
201+
}
193202
}
194203
/* }}} */
195204

@@ -749,7 +758,7 @@ PHPAPI void php_output_set_implicit_flush(int flush)
749758
* Get the file name where output has started */
750759
PHPAPI const char *php_output_get_start_filename(void)
751760
{
752-
return OG(output_start_filename);
761+
return ZSTR_VAL(OG(output_start_filename_str));
753762
}
754763
/* }}} */
755764

main/php_output.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,10 @@ ZEND_BEGIN_MODULE_GLOBALS(output)
137137
zend_stack handlers;
138138
php_output_handler *active;
139139
php_output_handler *running;
140-
const char *output_start_filename;
140+
const char *output_start_filename; /* TODO: Unused, remove */
141141
int output_start_lineno;
142142
int flags;
143+
zend_string *output_start_filename_str;
143144
ZEND_END_MODULE_GLOBALS(output)
144145

145146
PHPAPI ZEND_EXTERN_MODULE_GLOBALS(output)

0 commit comments

Comments
 (0)