php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #70970
Patch bug70970.patch revision 2015-11-25 16:09 UTC by laruence@php.net

Patch bug70970.patch for Output Control Bug #70970

Patch version 2015-11-25 16:09 UTC

Return to Bug #70970 | Download this patch
Patch Revisions:

Developer: laruence@php.net

diff --git a/main/output.c b/main/output.c
index 831c11f..4fcf0b4 100644
--- a/main/output.c
+++ b/main/output.c
@@ -189,6 +189,9 @@ PHPAPI void php_output_deactivate(void)
 		/* release all output handlers */
 		if (OG(handlers).elements) {
 			while ((handler = zend_stack_top(&OG(handlers)))) {
+				if (((*handler)->flags & PHP_OUTPUT_HANDLER_USER)) {
+					zend_fcall_info_args_clear(&(*handler)->func.user->fci, 1);
+				}
 				php_output_handler_free(handler);
 				zend_stack_del_top(&OG(handlers));
 			}
@@ -973,10 +976,14 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl
 				/* call failed, pass internal buffer along */
 				status = PHP_OUTPUT_HANDLER_FAILURE;
 			}
-
-			zend_fcall_info_argn(&handler->func.user->fci, 0);
 			zval_ptr_dtor(&retval);
 
+			if (OG(running)) {
+				zend_fcall_info_argn(&handler->func.user->fci, 0);
+				handler->flags |= PHP_OUTPUT_HANDLER_STARTED;
+			} else {
+				handler = NULL;
+			}
 		} else {
 
 			php_output_context_feed(context, handler->buffer.data, handler->buffer.size, handler->buffer.used, 0);
@@ -990,36 +997,38 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl
 			} else {
 				status = PHP_OUTPUT_HANDLER_FAILURE;
 			}
+			handler->flags |= PHP_OUTPUT_HANDLER_STARTED;
 		}
-		handler->flags |= PHP_OUTPUT_HANDLER_STARTED;
 		OG(running) = NULL;
 	}
 
-	switch (status) {
-		case PHP_OUTPUT_HANDLER_FAILURE:
-			/* disable this handler */
-			handler->flags |= PHP_OUTPUT_HANDLER_DISABLED;
-			/* discard any output */
-			if (context->out.data && context->out.free) {
-				efree(context->out.data);
-			}
-			/* returns handlers buffer */
-			context->out.data = handler->buffer.data;
-			context->out.used = handler->buffer.used;
-			context->out.free = 1;
-			handler->buffer.data = NULL;
-			handler->buffer.used = 0;
-			handler->buffer.size = 0;
-			break;
-		case PHP_OUTPUT_HANDLER_NO_DATA:
-			/* handler ate all */
-			php_output_context_reset(context);
-			/* no break */
-		case PHP_OUTPUT_HANDLER_SUCCESS:
-			/* no more buffered data */
-			handler->buffer.used = 0;
-			handler->flags |= PHP_OUTPUT_HANDLER_PROCESSED;
-			break;
+	if (handler) {
+		switch (status) {
+			case PHP_OUTPUT_HANDLER_FAILURE:
+				/* disable this handler */
+				handler->flags |= PHP_OUTPUT_HANDLER_DISABLED;
+				/* discard any output */
+				if (context->out.data && context->out.free) {
+					efree(context->out.data);
+				}
+				/* returns handlers buffer */
+				context->out.data = handler->buffer.data;
+				context->out.used = handler->buffer.used;
+				context->out.free = 1;
+				handler->buffer.data = NULL;
+				handler->buffer.used = 0;
+				handler->buffer.size = 0;
+				break;
+			case PHP_OUTPUT_HANDLER_NO_DATA:
+				/* handler ate all */
+				php_output_context_reset(context);
+				/* no break */
+			case PHP_OUTPUT_HANDLER_SUCCESS:
+				/* no more buffered data */
+				handler->buffer.used = 0;
+				handler->flags |= PHP_OUTPUT_HANDLER_PROCESSED;
+				break;
+		}
 	}
 
 	context->op = original_op;
@@ -1221,21 +1230,24 @@ static inline int php_output_stack_pop(int flags)
 			php_output_handler_op(orphan, &context);
 		}
 
-		/* pop it off the stack */
-		zend_stack_del_top(&OG(handlers));
-		if ((current = zend_stack_top(&OG(handlers)))) {
-			OG(active) = *current;
-		} else {
-			OG(active) = NULL;
-		}
+		if (OG(flags) & PHP_OUTPUT_ACTIVATED) {
+			/* pop it off the stack */
+			zend_stack_del_top(&OG(handlers));
+			if ((current = zend_stack_top(&OG(handlers)))) {
+				OG(active) = *current;
+			} else {
+				OG(active) = NULL;
+			}
 
-		/* pass output along */
-		if (context.out.data && context.out.used && !(flags & PHP_OUTPUT_POP_DISCARD)) {
-			php_output_write(context.out.data, context.out.used);
+			/* pass output along */
+			if (context.out.data && context.out.used && !(flags & PHP_OUTPUT_POP_DISCARD)) {
+				php_output_write(context.out.data, context.out.used);
+			}
+
+			/* destroy the handler (after write!) */
+			php_output_handler_free(&orphan);
 		}
 
-		/* destroy the handler (after write!) */
-		php_output_handler_free(&orphan);
 		php_output_context_dtor(&context);
 
 		return 1;
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Sat May 21 13:05:45 2022 UTC