mike            Tue Aug 22 07:53:58 2006 UTC

  Modified files:              
    /php-src/main       output.c php_output.h 
  Log:
  - allocate handler stack on the heap and avoid segfaults on shutdown when 
startup fails
  - don't try to append empty buffer
  - fix some dbg format strings
  
http://cvs.php.net/viewvc.cgi/php-src/main/output.c?r1=1.187&r2=1.188&diff_format=u
Index: php-src/main/output.c
diff -u php-src/main/output.c:1.187 php-src/main/output.c:1.188
--- php-src/main/output.c:1.187 Wed Aug  9 13:56:45 2006
+++ php-src/main/output.c       Tue Aug 22 07:53:58 2006
@@ -19,7 +19,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: output.c,v 1.187 2006/08/09 13:56:45 mike Exp $ */
+/* $Id: output.c,v 1.188 2006/08/22 07:53:58 mike Exp $ */
 
 #ifndef PHP_OUTPUT_DEBUG
 #      define PHP_OUTPUT_DEBUG 0
@@ -112,7 +112,9 @@
 #else
        memset(&output_globals, 0, sizeof(zend_output_globals));
 #endif
-       if (SUCCESS != zend_stack_init(&OG(handlers))) {
+       
+       OG(handlers) = emalloc(sizeof(zend_stack));
+       if (SUCCESS != zend_stack_init(OG(handlers))) {
                return FAILURE;
        }
        
@@ -133,15 +135,26 @@
        
        OG(active) = NULL;
        OG(running) = NULL;
+       
        /* release all output handlers */
-       while (SUCCESS == zend_stack_top(&OG(handlers), (void *) &handler)) {
-               php_output_handler_free(handler TSRMLS_CC);
-               zend_stack_del_top(&OG(handlers));
+       if (OG(handlers)) {
+               while (SUCCESS == zend_stack_top(OG(handlers), (void *) 
&handler)) {
+                       php_output_handler_free(handler TSRMLS_CC);
+                       zend_stack_del_top(OG(handlers));
+               }
+               zend_stack_destroy(OG(handlers));
+               efree(OG(handlers));
+               OG(handlers) = NULL;
        }
-       zend_stack_destroy(&OG(handlers));
        
-       zval_ptr_dtor(&OG(default_output_handler_name));
-       zval_ptr_dtor(&OG(devnull_output_handler_name));
+       if (OG(default_output_handler_name)) {
+               zval_ptr_dtor(&OG(default_output_handler_name));
+               OG(default_output_handler_name) = NULL;
+       }
+       if (OG(devnull_output_handler_name)) {
+               zval_ptr_dtor(&OG(devnull_output_handler_name));
+               OG(devnull_output_handler_name) = NULL;
+       }
 }
 /* }}} */
 
@@ -277,9 +290,9 @@
                php_output_context_init(&context, PHP_OUTPUT_HANDLER_FLUSH 
TSRMLS_CC);
                php_output_handler_op(OG(active), &context);
                if (context.out.data && context.out.used) {
-                       zend_stack_del_top(&OG(handlers));
+                       zend_stack_del_top(OG(handlers));
                        php_output_write(context.out.data, context.out.used 
TSRMLS_CC);
-                       zend_stack_push(&OG(handlers), &OG(active), 
sizeof(php_output_handler *));
+                       zend_stack_push(OG(handlers), &OG(active), 
sizeof(php_output_handler *));
                }
                php_output_context_dtor(&context);
                return SUCCESS;
@@ -323,7 +336,7 @@
        
        if (OG(active)) {
                php_output_context_init(&context, PHP_OUTPUT_HANDLER_CLEAN 
TSRMLS_CC);
-               zend_stack_apply_with_argument(&OG(handlers), 
ZEND_STACK_APPLY_TOPDOWN, php_output_stack_apply_clean, &context);
+               zend_stack_apply_with_argument(OG(handlers), 
ZEND_STACK_APPLY_TOPDOWN, php_output_stack_apply_clean, &context);
        }
 }
 
@@ -371,7 +384,7 @@
        Get output buffering level, ie. how many output handlers the stack 
contains */
 PHPAPI int php_output_get_level(TSRMLS_D)
 {
-       return OG(active) ? zend_stack_count(&OG(handlers)) : 0;
+       return OG(active) ? zend_stack_count(OG(handlers)) : 0;
 }
 /* }}} */
 
@@ -549,7 +562,7 @@
                }
        }
        /* zend_stack_push never returns SUCCESS but FAILURE or stack level */
-       if (FAILURE == (handler->level = zend_stack_push(&OG(handlers), 
&handler, sizeof(php_output_handler *)))) {
+       if (FAILURE == (handler->level = zend_stack_push(OG(handlers), 
&handler, sizeof(php_output_handler *)))) {
                return FAILURE;
        }
        OG(active) = handler;
@@ -565,7 +578,7 @@
        int i, count = php_output_get_level(TSRMLS_C);
        
        if (count) {
-               handlers = (php_output_handler **) 
zend_stack_base(&OG(handlers));
+               handlers = (php_output_handler **) 
zend_stack_base(OG(handlers));
                
                for (i = 0; i < count; ++i) {
                        if (!zend_binary_zval_strcmp(handlers[i]->name, name)) {
@@ -842,22 +855,24 @@
        Appends input to the output handlers buffer and indicates whether the 
buffer does not have to be processed by the output handler */
 static inline int php_output_handler_append(php_output_handler *handler, const 
php_output_buffer *buf TSRMLS_DC)
 {
-       /* store it away */
-       if ((handler->buffer.size - handler->buffer.used) <= buf->used) {
-               size_t grow_int = 
PHP_OUTPUT_HANDLER_INITBUF_SIZE(handler->size);
-               size_t grow_buf = PHP_OUTPUT_HANDLER_INITBUF_SIZE(buf->used + 1 
- (handler->buffer.size - handler->buffer.used));
-               size_t grow_max = MAX(grow_int, grow_buf);
+       if (buf->used) {
+               /* store it away */
+               if ((handler->buffer.size - handler->buffer.used) <= buf->used) 
{
+                       size_t grow_int = 
PHP_OUTPUT_HANDLER_INITBUF_SIZE(handler->size);
+                       size_t grow_buf = 
PHP_OUTPUT_HANDLER_INITBUF_SIZE(buf->used + 1 - (handler->buffer.size - 
handler->buffer.used));
+                       size_t grow_max = MAX(grow_int, grow_buf);
                
-               handler->buffer.data = erealloc(handler->buffer.data, 
handler->buffer.size += grow_max);
-       }
-       memcpy(handler->buffer.data + handler->buffer.used, buf->data, 
buf->used);
-       handler->buffer.used += buf->used;
-       handler->buffer.data[handler->buffer.used] = '\0';
-       
-       /* chunked buffering */
-       if (handler->size && (handler->buffer.used >= handler->size)) {
-               /* store away errors and/or any intermediate output */
-               return OG(running) ? 1 : 0;
+                       handler->buffer.data = erealloc(handler->buffer.data, 
handler->buffer.size += grow_max);
+               }
+               memcpy(handler->buffer.data + handler->buffer.used, buf->data, 
buf->used);
+               handler->buffer.used += buf->used;
+               handler->buffer.data[handler->buffer.used] = '\0';
+       
+               /* chunked buffering */
+               if (handler->size && (handler->buffer.used >= handler->size)) {
+                       /* store away errors and/or any intermediate output */
+                       return OG(running) ? 1 : 0;
+               }
        }
        return 1;
 }
@@ -876,18 +891,18 @@
                                        "name=%s, "
                                        "flags=%d, "
                                        "buffer.data=%s, "
-                                       "buffer.used=%lu, "
-                                       "buffer.size=%lu, "
+                                       "buffer.used=%zu, "
+                                       "buffer.size=%zu, "
                                        "in.data=%s, "
-                                       "in.used=%lu)\n",
+                                       "in.used=%zu)\n",
                        context->op,
                        handler,
-                       handler->name,
+                       Z_STRVAL_P(handler->name),
                        handler->flags,
-                       handler->buffer.data,
+                       handler->buffer.used?handler->buffer.data:"",
                        handler->buffer.used,
                        handler->buffer.size,
-                       context->in.data,
+                       context->in.used?context->in.data:"",
                        context->in.used
        );
 #endif
@@ -913,6 +928,7 @@
                        zval *retval = NULL, **params[2], *flags, *input;
                        
                        MAKE_STD_ZVAL(input);
+                       /* can we avoid copying here by setting is_ref? */
                        ZVAL_STRINGL(input, handler->buffer.data, 
handler->buffer.used, 1);
                        MAKE_STD_ZVAL(flags);
                        ZVAL_LONG(flags, (long) op);
@@ -1006,13 +1022,13 @@
         *  - apply op to the one active handler; note that OG(active) might be 
popped off the stack on a flush
         *  - or apply op to the handler stack
         */
-       if (OG(active) && (obh_cnt = zend_stack_count(&OG(handlers)))) {
+       if (OG(active) && (obh_cnt = zend_stack_count(OG(handlers)))) {
                context.in.data = (char *) str;
                context.in.used = len;
                
                if (obh_cnt > 1) {
-                       zend_stack_apply_with_argument(&OG(handlers), 
ZEND_STACK_APPLY_TOPDOWN, php_output_stack_apply_op, &context);
-               } else if ((SUCCESS == zend_stack_top(&OG(handlers), (void *) 
&active)) && (!((*active)->flags & PHP_OUTPUT_HANDLER_DISABLED))) {
+                       zend_stack_apply_with_argument(OG(handlers), 
ZEND_STACK_APPLY_TOPDOWN, php_output_stack_apply_op, &context);
+               } else if ((SUCCESS == zend_stack_top(OG(handlers), (void *) 
&active)) && (!((*active)->flags & PHP_OUTPUT_HANDLER_DISABLED))) {
                        php_output_handler_op(*active, &context);
                } else {
                        php_output_context_pass(&context);
@@ -1025,7 +1041,7 @@
        if (context.out.data) {
                if (context.out.used) {
 #if PHP_OUTPUT_DEBUG
-                       fprintf(stderr, "::: sapi_write('%s', %lu)\n", 
context.out.data, context.out.used);
+                       fprintf(stderr, "::: sapi_write('%s', %zu)\n", 
context.out.data, context.out.used);
 #endif
                        if (!SG(headers_sent) && php_header(TSRMLS_C)) {
                                if (zend_is_compiling(TSRMLS_C)) {
@@ -1193,8 +1209,8 @@
                }
                
                /* pop it off the stack */
-               zend_stack_del_top(&OG(handlers));
-               if (SUCCESS == zend_stack_top(&OG(handlers), (void *) 
&current)) {
+               zend_stack_del_top(OG(handlers));
+               if (SUCCESS == zend_stack_top(OG(handlers), (void *) &current)) 
{
                        OG(active) = *current;
                } else {
                        OG(active) = NULL;
@@ -1438,7 +1454,7 @@
        }
        
        array_init(return_value);
-       zend_stack_apply_with_argument(&OG(handlers), 
ZEND_STACK_APPLY_BOTTOMUP, php_output_stack_apply_list, return_value);
+       zend_stack_apply_with_argument(OG(handlers), ZEND_STACK_APPLY_BOTTOMUP, 
php_output_stack_apply_list, return_value);
 }
 /* }}} */
 
@@ -1457,7 +1473,7 @@
        
        array_init(return_value);
        if (full_status) {
-               zend_stack_apply_with_argument(&OG(handlers), 
ZEND_STACK_APPLY_BOTTOMUP, php_output_stack_apply_status, return_value);
+               zend_stack_apply_with_argument(OG(handlers), 
ZEND_STACK_APPLY_BOTTOMUP, php_output_stack_apply_status, return_value);
        } else {
                php_output_handler_status(OG(active), return_value);
        }
http://cvs.php.net/viewvc.cgi/php-src/main/php_output.h?r1=1.60&r2=1.61&diff_format=u
Index: php-src/main/php_output.h
diff -u php-src/main/php_output.h:1.60 php-src/main/php_output.h:1.61
--- php-src/main/php_output.h:1.60      Wed Aug  9 13:56:45 2006
+++ php-src/main/php_output.h   Tue Aug 22 07:53:58 2006
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_output.h,v 1.60 2006/08/09 13:56:45 mike Exp $ */
+/* $Id: php_output.h,v 1.61 2006/08/22 07:53:58 mike Exp $ */
 
 #ifndef PHP_OUTPUT_H
 #define PHP_OUTPUT_H
@@ -117,7 +117,7 @@
 
 ZEND_BEGIN_MODULE_GLOBALS(output)
        int flags;
-       zend_stack handlers;
+       zend_stack *handlers;
        php_output_handler *active;
        php_output_handler *running;
        char *output_start_filename;

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to