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;
|