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