1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix output buffer discard on memory limit

Move this code directly into the error handler, and check the
heap->overflow flag. Discarding output here allows us to print
the normal memory limit message to standard output. Otherwise
nothing would be printed unless a different log medium was used,
which makes for a suboptimal debugging experience.
This commit is contained in:
Nikita Popov
2021-05-31 16:30:36 +02:00
parent 3a4ea6cb91
commit e9b005158f
4 changed files with 16 additions and 17 deletions

View File

@@ -2669,6 +2669,15 @@ ZEND_API zend_result zend_set_memory_limit(size_t memory_limit)
return SUCCESS;
}
ZEND_API bool zend_alloc_in_memory_limit_error_reporting(void)
{
#if ZEND_MM_LIMIT
return AG(mm_heap)->overflow;
#else
return false;
#endif
}
ZEND_API size_t zend_memory_usage(bool real_usage)
{
#if ZEND_MM_STAT

View File

@@ -220,6 +220,7 @@ ZEND_API void * __zend_realloc(void *p, size_t len) ZEND_ATTRIBUTE_ALLOC_SIZE(2)
#define pestrdup_rel(s, persistent) ((persistent)?strdup(s):estrdup_rel(s))
ZEND_API zend_result zend_set_memory_limit(size_t memory_limit);
ZEND_API bool zend_alloc_in_memory_limit_error_reporting(void);
ZEND_API void start_memory_manager(void);
ZEND_API void shutdown_memory_manager(bool silent, bool full_shutdown);

View File

@@ -1235,6 +1235,10 @@ static ZEND_COLD void php_error_cb(int orig_type, zend_string *error_filename, c
PG(last_error_lineno) = error_lineno;
}
if (zend_alloc_in_memory_limit_error_reporting()) {
php_output_discard_all();
}
/* display/log the error if necessary */
if (display && ((EG(error_reporting) & type) || (type & E_CORE))
&& (PG(log_errors) || PG(display_errors) || (!module_initialized))) {
@@ -1783,19 +1787,7 @@ void php_request_shutdown(void *dummy)
/* 3. Flush all output buffers */
zend_try {
bool send_buffer = SG(request_info).headers_only ? 0 : 1;
if (CG(unclean_shutdown) && PG(last_error_type) == E_ERROR &&
(size_t)PG(memory_limit) < zend_memory_usage(1)
) {
send_buffer = 0;
}
if (!send_buffer) {
php_output_discard_all();
} else {
php_output_end_all();
}
php_output_end_all();
} zend_end_try();
/* 4. Reset max_execution_time (no longer executing php code after response sent) */

View File

@@ -1,9 +1,5 @@
--TEST--
Bug #45392 (ob_start()/ob_end_clean() and memory_limit)
--INI--
display_errors=stderr
--XFAIL--
The issue has not yet been resolved.
--SKIPIF--
<?php
if (getenv("USE_ZEND_ALLOC") === "0") {
@@ -22,4 +18,5 @@ ob_end_clean();
?>
--EXPECTF--
2
Fatal error: Allowed memory size of %d bytes exhausted%s