Hi, Attached is a proposed fix for http://bugs.php.net/bug.php?id=45392 for PHP_5_3. I don't know output buffering part very well, and I'm not completely sure about this fix, so please review it.
The patch changes behavior of output buffering a bit. In case of fatal error all output buffers opened by ob_start() with zero (or omitted) chunk_size argument are discarded. The fix brakes two tests: Test session_module_name() function : variation [ext/session/tests/session_module_name_variation3.phpt] Test session_set_save_handler() function : error functionality [ext/session/tests/session_set_save_handler_error3.phpt] We need to make a decision about #45392. 1) Fix it with proposed (or similar) patch 2) Make it bogus because any fix requires output buffering behavior change Thanks. Dmitry.
Index: NEWS =================================================================== RCS file: /repository/php-src/NEWS,v retrieving revision 1.2027.2.547.2.965.2.305 diff -u -p -d -r1.2027.2.547.2.965.2.305 NEWS --- NEWS 1 Sep 2008 20:51:57 -0000 1.2027.2.547.2.965.2.305 +++ NEWS 2 Sep 2008 08:31:03 -0000 @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 200?, PHP 5.3.0 Alpha 3 +- Fixed bug #45392 (ob_start()/ob_end_clean() and memory_limit. In case of + fatal error active output buffers with zero chunk_size (the default value of + the second argument to ob_start()) are discarded). (Dmitry) 02 Sep 2008, PHP 5.3.0 Alpha 2 - Removed special treatment of "/tmp" in sessions for open_basedir. Index: main/main.c =================================================================== RCS file: /repository/php-src/main/main.c,v retrieving revision 1.640.2.23.2.57.2.32 diff -u -p -d -r1.640.2.23.2.57.2.32 main.c --- main/main.c 26 Aug 2008 23:26:07 -0000 1.640.2.23.2.57.2.32 +++ main/main.c 2 Sep 2008 08:31:03 -0000 @@ -852,6 +852,19 @@ static void php_error_cb(int type, const } } + if (!SG(request_info).headers_only) { + /* Discard output buffers with zero chunk_size on fatal error */ + switch (type) { + case E_CORE_ERROR: + case E_ERROR: + case E_RECOVERABLE_ERROR: + case E_PARSE: + case E_COMPILE_ERROR: + case E_USER_ERROR: + php_discard_ob_buffers(TSRMLS_C); + } + } + /* display/log the error if necessary */ if (display && (EG(error_reporting) & type || (type & E_CORE)) && (PG(log_errors) || PG(display_errors) || (!module_initialized))) { Index: main/output.c =================================================================== RCS file: /repository/php-src/main/output.c,v retrieving revision 1.167.2.3.2.4.2.9 diff -u -p -d -r1.167.2.3.2.4.2.9 output.c --- main/output.c 18 Aug 2008 07:46:31 -0000 1.167.2.3.2.4.2.9 +++ main/output.c 2 Sep 2008 08:31:03 -0000 @@ -341,6 +341,45 @@ PHPAPI void php_end_ob_buffers(zend_bool } /* }}} */ +typedef struct _php_ob_calc_discard_rec { + int count; + int last; +} php_ob_calc_discard_rec; + +/* {{{ php_ob_list_each + */ +static int php_ob_calc_discard(php_ob_buffer *ob_buffer, php_ob_calc_discard_rec *discard) +{ + discard->count++; + if (!ob_buffer->chunk_size) { + discard->last = discard->count; + } + return 0; +} +/* }}} */ + + +/* {{{ php_discard_ob_buffers + * Discard output buffers with zero chunk_size */ +PHPAPI void php_discard_ob_buffers(TSRMLS_D) +{ + if (OG(ob_nesting_level)) { + php_ob_calc_discard_rec discard; + + discard.count = 0; + discard.last = 0; + php_ob_calc_discard(&OG(active_ob_buffer), &discard); + if (OG(ob_nesting_level)>1) { + zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element, void *)) php_ob_calc_discard, &discard); + } + while (discard.last) { + php_end_ob_buffer(OG(active_ob_buffer).chunk_size != 0, 0 TSRMLS_CC); + discard.last--; + } + } +} +/* }}} */ + /* {{{ php_start_implicit_flush */ PHPAPI void php_start_implicit_flush(TSRMLS_D) Index: main/php_output.h =================================================================== RCS file: /repository/php-src/main/php_output.h,v retrieving revision 1.53.2.1.2.1.2.1 diff -u -p -d -r1.53.2.1.2.1.2.1 php_output.h --- main/php_output.h 31 Dec 2007 07:17:17 -0000 1.53.2.1.2.1.2.1 +++ main/php_output.h 2 Sep 2008 08:31:03 -0000 @@ -37,6 +37,7 @@ PHPAPI int php_start_ob_buffer(zval *out PHPAPI int php_start_ob_buffer_named(const char *output_handler_name, uint chunk_size, zend_bool erase TSRMLS_DC); PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS_DC); PHPAPI void php_end_ob_buffers(zend_bool send_buffer TSRMLS_DC); +PHPAPI void php_discard_ob_buffers(TSRMLS_D); PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC); PHPAPI int php_ob_get_length(zval *p TSRMLS_DC); PHPAPI void php_start_implicit_flush(TSRMLS_D);
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php