PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - main - output.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 443 488 90.8 %
Date: 2014-04-18 Functions: 46 47 97.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 5                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2013 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Zeev Suraski <zeev@zend.com>                                |
      16             :    |          Thies C. Arntzen <thies@thieso.net>                         |
      17             :    |          Marcus Boerger <helly@php.net>                              |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include "php.h"
      24             : #include "ext/standard/head.h"
      25             : #include "ext/standard/basic_functions.h"
      26             : #include "ext/standard/url_scanner_ex.h"
      27             : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
      28             : #include "ext/zlib/php_zlib.h"
      29             : #endif
      30             : #include "SAPI.h"
      31             : 
      32             : #define OB_DEFAULT_HANDLER_NAME "default output handler"
      33             : 
      34             : /* output functions */
      35             : static int php_b_body_write(const char *str, uint str_length TSRMLS_DC);
      36             : 
      37             : static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC);
      38             : static void php_ob_append(const char *text, uint text_length TSRMLS_DC);
      39             : #if 0
      40             : static void php_ob_prepend(const char *text, uint text_length);
      41             : #endif
      42             : 
      43             : #ifdef ZTS
      44             : int output_globals_id;
      45             : #else
      46             : php_output_globals output_globals;
      47             : #endif
      48             : 
      49             : /* {{{ php_default_output_func */
      50          46 : PHPAPI int php_default_output_func(const char *str, uint str_len TSRMLS_DC)
      51             : {
      52          46 :         fwrite(str, 1, str_len, stderr);
      53             : /* See http://support.microsoft.com/kb/190351 */
      54             : #ifdef PHP_WIN32
      55             :         fflush(stderr);
      56             : #endif
      57          46 :         return str_len;
      58             : }
      59             : /* }}} */
      60             : 
      61             : /* {{{ php_output_init_globals */
      62       19341 : static void php_output_init_globals(php_output_globals *output_globals_p TSRMLS_DC)
      63             : {
      64       19341 :         OG(php_body_write) = php_default_output_func;
      65       19341 :         OG(php_header_write) = php_default_output_func;
      66       19341 :         OG(implicit_flush) = 0;
      67       19341 :         OG(output_start_filename) = NULL;
      68       19341 :         OG(output_start_lineno) = 0;
      69       19341 : }
      70             : /* }}} */
      71             : 
      72             : /* {{{ php_output_startup
      73             :  * Start output layer */
      74       19341 : PHPAPI void php_output_startup(void)
      75             : {
      76             : #ifdef ZTS
      77             :         ts_allocate_id(&output_globals_id, sizeof(php_output_globals), (ts_allocate_ctor) php_output_init_globals, NULL);
      78             : #else
      79       19341 :         php_output_init_globals(&output_globals TSRMLS_CC);
      80             : #endif
      81       19341 : }
      82             : /* }}} */
      83             : 
      84             : /* {{{ php_output_activate
      85             :  * Initilize output global for activation */
      86       19327 : PHPAPI void php_output_activate(TSRMLS_D)
      87             : {
      88       19327 :         OG(php_body_write) = php_ub_body_write;
      89       19327 :         OG(php_header_write) = sapi_module.ub_write;
      90       19327 :         OG(ob_nesting_level) = 0;
      91       19327 :         OG(ob_lock) = 0;
      92       19327 :         OG(disable_output) = 0;
      93       19327 :         OG(output_start_filename) = NULL;
      94       19327 :         OG(output_start_lineno) = 0;
      95       19327 : }
      96             : /* }}} */
      97             : 
      98             : /* {{{ php_output_register_constants */
      99       19341 : void php_output_register_constants(TSRMLS_D)
     100             : {
     101       19341 :         REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_START", PHP_OUTPUT_HANDLER_START, CONST_CS | CONST_PERSISTENT);
     102       19341 :         REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_CONT", PHP_OUTPUT_HANDLER_CONT, CONST_CS | CONST_PERSISTENT);
     103       19341 :         REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_END", PHP_OUTPUT_HANDLER_END, CONST_CS | CONST_PERSISTENT);
     104       19341 : }
     105             : /* }}} */
     106             : 
     107             : /* {{{ php_output_set_status
     108             :  * Toggle output status.  Do NOT use in application code, only in SAPIs where appropriate. */
     109           2 : PHPAPI void php_output_set_status(zend_bool status TSRMLS_DC)
     110             : {
     111           2 :         OG(disable_output) = !status;
     112           2 : }
     113             : /* }}} */
     114             : 
     115             : /* {{{ php_body_write
     116             :  * Write body part */
     117     1602918 : PHPAPI int php_body_write(const char *str, uint str_length TSRMLS_DC)
     118             : {
     119     1602918 :         return OG(php_body_write)(str, str_length TSRMLS_CC);
     120             : }
     121             : /* }}} */
     122             : 
     123             : /* {{{ php_header_write
     124             :  * Write HTTP header */
     125        1141 : PHPAPI int php_header_write(const char *str, uint str_length TSRMLS_DC)
     126             : {
     127        1141 :         if (OG(disable_output)) {
     128           0 :                 return 0;
     129             :         } else {
     130        1141 :                 return OG(php_header_write)(str, str_length TSRMLS_CC);
     131             :         }
     132             : }
     133             : /* }}} */
     134             : 
     135             : /* {{{ php_start_ob_buffer
     136             :  * Start output buffering */
     137        4899 : PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
     138             : {
     139             :         uint initial_size, block_size;
     140             : 
     141        4899 :         if (OG(ob_lock)) {
     142           2 :                 if (SG(headers_sent) && !SG(request_info).headers_only) {
     143           0 :                         OG(php_body_write) = php_ub_body_write_no_header;
     144             :                 } else {
     145           2 :                         OG(php_body_write) = php_ub_body_write;
     146             :                 }
     147           2 :                 OG(ob_nesting_level) = 0;
     148           2 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_ERROR, "Cannot use output buffering in output buffering display handlers");
     149           0 :                 return FAILURE;
     150             :         }
     151        4897 :         if (chunk_size > 0) {
     152         175 :                 if (chunk_size==1) {
     153           3 :                         chunk_size = 4096;
     154             :                 }
     155         175 :                 initial_size = (chunk_size*3/2);
     156         175 :                 block_size = chunk_size/2;
     157             :         } else {
     158        4722 :                 initial_size = 40*1024;
     159        4722 :                 block_size = 10*1024;
     160             :         }
     161        4897 :         return php_ob_init(initial_size, block_size, output_handler, chunk_size, erase TSRMLS_CC);
     162             : }
     163             : /* }}} */
     164             : 
     165             : /* {{{ php_start_ob_buffer_named
     166             :  * Start output buffering */
     167           6 : PHPAPI int php_start_ob_buffer_named(const char *output_handler_name, uint chunk_size, zend_bool erase TSRMLS_DC)
     168             : {
     169             :         zval *output_handler;
     170             :         int result;
     171             : 
     172           6 :         ALLOC_INIT_ZVAL(output_handler);
     173           6 :         Z_STRLEN_P(output_handler) = strlen(output_handler_name);       /* this can be optimized */
     174           6 :         Z_STRVAL_P(output_handler) = estrndup(output_handler_name, Z_STRLEN_P(output_handler));
     175           6 :         Z_TYPE_P(output_handler) = IS_STRING;
     176           6 :         result = php_start_ob_buffer(output_handler, chunk_size, erase TSRMLS_CC);
     177           6 :         zval_dtor(output_handler);
     178           6 :         FREE_ZVAL(output_handler);
     179           6 :         return result;
     180             : }
     181             : /* }}} */
     182             : 
     183             : /* {{{ php_end_ob_buffer
     184             :  * End output buffering (one level) */
     185        6132 : PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS_DC)
     186             : {
     187        6132 :         char *final_buffer=NULL;
     188        6132 :         unsigned int final_buffer_length=0;
     189        6132 :         zval *alternate_buffer=NULL;
     190             :         char *to_be_destroyed_buffer, *to_be_destroyed_handler_name;
     191        6132 :         char *to_be_destroyed_handled_output[2] = { 0, 0 };
     192             :         int status;
     193        6132 :         php_ob_buffer *prev_ob_buffer_p=NULL;
     194             :         php_ob_buffer orig_ob_buffer;
     195             : 
     196        6132 :         if (OG(ob_nesting_level)==0) {
     197           1 :                 return;
     198             :         }
     199        6131 :         status = 0;
     200        6131 :         if (!OG(active_ob_buffer).status & PHP_OUTPUT_HANDLER_START) {
     201             :                 /* our first call */
     202        4898 :                 status |= PHP_OUTPUT_HANDLER_START;
     203             :         }
     204        6131 :         if (just_flush) {
     205        1233 :                 status |= PHP_OUTPUT_HANDLER_CONT;
     206             :         } else {
     207        4898 :                 status |= PHP_OUTPUT_HANDLER_END;
     208             :         }
     209             : 
     210             : #if 0
     211             :  {
     212             :          FILE *fp;
     213             :          fp = fopen("/tmp/ob_log", "a");
     214             :          fprintf(fp, "NestLevel: %d  ObStatus: %d  HandlerName: %s\n", OG(ob_nesting_level), status, OG(active_ob_buffer).handler_name);
     215             :          fclose(fp);
     216             :  }
     217             : #endif
     218             : 
     219        6131 :         if (OG(active_ob_buffer).internal_output_handler) {
     220          18 :                 final_buffer = OG(active_ob_buffer).internal_output_handler_buffer;
     221          18 :                 final_buffer_length = OG(active_ob_buffer).internal_output_handler_buffer_size;
     222          18 :                 OG(active_ob_buffer).internal_output_handler(OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length, &final_buffer, &final_buffer_length, status TSRMLS_CC);
     223        6113 :         } else if (OG(active_ob_buffer).output_handler) {
     224             :                 zval **params[2];
     225             :                 zval *orig_buffer;
     226             :                 zval *z_status;
     227             : 
     228         127 :                 if(OG(ob_lock)) {
     229           1 :                         if (SG(headers_sent) && !SG(request_info).headers_only) {
     230           0 :                                 OG(php_body_write) = php_ub_body_write_no_header;
     231             :                         } else {
     232           1 :                                 OG(php_body_write) = php_ub_body_write;
     233             :                         }
     234           1 :                         OG(ob_nesting_level) = 0;
     235           1 :                         php_error_docref("ref.outcontrol" TSRMLS_CC, E_ERROR, "Cannot use output buffering in output buffering display handlers");
     236           0 :                         return;
     237             :                 }
     238             : 
     239         126 :                 ALLOC_INIT_ZVAL(orig_buffer);
     240         126 :                 ZVAL_STRINGL(orig_buffer, OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length, 1);
     241             : 
     242         126 :                 ALLOC_INIT_ZVAL(z_status);
     243         126 :                 ZVAL_LONG(z_status, status);
     244             : 
     245         126 :                 params[0] = &orig_buffer;
     246         126 :                 params[1] = &z_status;
     247         126 :                 OG(ob_lock) = 1;
     248             : 
     249         126 :                 if (call_user_function_ex(CG(function_table), NULL, OG(active_ob_buffer).output_handler, &alternate_buffer, 2, params, 1, NULL TSRMLS_CC)==SUCCESS) {
     250         123 :                         if (alternate_buffer && !(Z_TYPE_P(alternate_buffer)==IS_BOOL && Z_BVAL_P(alternate_buffer)==0)) {
     251         136 :                                 convert_to_string_ex(&alternate_buffer);
     252         121 :                                 final_buffer = Z_STRVAL_P(alternate_buffer);
     253         121 :                                 final_buffer_length = Z_STRLEN_P(alternate_buffer);
     254             :                         }
     255             :                 }
     256         123 :                 OG(ob_lock) = 0;
     257         123 :                 if (!just_flush) {
     258          94 :                         zval_ptr_dtor(&OG(active_ob_buffer).output_handler);
     259             :                 }
     260         123 :                 zval_ptr_dtor(&orig_buffer);
     261         123 :                 zval_ptr_dtor(&z_status);
     262             :         }
     263             : 
     264        6127 :         if (!final_buffer) {
     265        5990 :                 final_buffer = OG(active_ob_buffer).buffer;
     266        5990 :                 final_buffer_length = OG(active_ob_buffer).text_length;
     267             :         }
     268             : 
     269        6127 :         if (OG(ob_nesting_level)==1) { /* end buffering */
     270        8724 :                 if (SG(headers_sent) && !SG(request_info).headers_only) {
     271        4057 :                         OG(php_body_write) = php_ub_body_write_no_header;
     272             :                 } else {
     273         610 :                         OG(php_body_write) = php_ub_body_write;
     274             :                 }
     275             :         }
     276             : 
     277        6127 :         to_be_destroyed_buffer = OG(active_ob_buffer).buffer;
     278        6127 :         to_be_destroyed_handler_name = OG(active_ob_buffer).handler_name;
     279        6160 :         if (OG(active_ob_buffer).internal_output_handler
     280        6145 :                 && (final_buffer != OG(active_ob_buffer).internal_output_handler_buffer)
     281          15 :                 && (final_buffer != OG(active_ob_buffer).buffer)) {
     282          13 :                 to_be_destroyed_handled_output[0] = final_buffer;
     283             :         }
     284             : 
     285        6127 :         if (!just_flush) {
     286        4894 :                 if (OG(active_ob_buffer).internal_output_handler) {
     287          13 :                         to_be_destroyed_handled_output[1] = OG(active_ob_buffer).internal_output_handler_buffer;
     288             :                 }
     289             :         }
     290        6127 :         if (OG(ob_nesting_level)>1) { /* restore previous buffer */
     291        1460 :                 zend_stack_top(&OG(ob_buffers), (void **) &prev_ob_buffer_p);
     292        1460 :                 orig_ob_buffer = OG(active_ob_buffer);
     293        1460 :                 OG(active_ob_buffer) = *prev_ob_buffer_p;
     294        1460 :                 zend_stack_del_top(&OG(ob_buffers));
     295        1460 :                 if (!just_flush && OG(ob_nesting_level)==2) { /* destroy the stack */
     296         308 :                         zend_stack_destroy(&OG(ob_buffers));
     297             :                 }
     298             :         }
     299        6127 :         OG(ob_nesting_level)--;
     300             : 
     301        6127 :         if (send_buffer) {
     302        1683 :                 if (just_flush) { /* if flush is called prior to proper end, ensure presence of NUL */
     303        1226 :                         final_buffer[final_buffer_length] = '\0';
     304             :                 }
     305        1683 :                 OG(php_body_write)(final_buffer, final_buffer_length TSRMLS_CC);
     306             :         }
     307             : 
     308        6127 :         if (just_flush) { /* we restored the previous ob, return to the current */
     309        1233 :                 if (prev_ob_buffer_p) {
     310        1142 :                         zend_stack_push(&OG(ob_buffers), &OG(active_ob_buffer), sizeof(php_ob_buffer));
     311        1142 :                         OG(active_ob_buffer) = orig_ob_buffer;
     312             :                 }
     313        1233 :                 OG(ob_nesting_level)++;
     314             :         }
     315             : 
     316        6127 :         if (alternate_buffer) {
     317         122 :                 zval_ptr_dtor(&alternate_buffer);
     318             :         }
     319             : 
     320        6127 :         if (status & PHP_OUTPUT_HANDLER_END) {
     321        4894 :                 efree(to_be_destroyed_handler_name);
     322             :         }
     323        6127 :         if (!just_flush) {
     324        4894 :                 efree(to_be_destroyed_buffer);
     325             :         } else {
     326        1233 :                 OG(active_ob_buffer).text_length = 0;
     327        1233 :                 OG(active_ob_buffer).status |= PHP_OUTPUT_HANDLER_START;
     328        1233 :                 OG(php_body_write) = php_b_body_write;
     329             :         }
     330        6127 :         if (to_be_destroyed_handled_output[0]) {
     331          13 :                 efree(to_be_destroyed_handled_output[0]);
     332             :         }
     333        6127 :         if (to_be_destroyed_handled_output[1]) {
     334          13 :                 efree(to_be_destroyed_handled_output[1]);
     335             :         }
     336             : }
     337             : /* }}} */
     338             : 
     339             : /* {{{ php_end_ob_buffers
     340             :  * End output buffering (all buffers) */
     341       19393 : PHPAPI void php_end_ob_buffers(zend_bool send_buffer TSRMLS_DC)
     342             : {
     343       38887 :         while (OG(ob_nesting_level)!=0) {
     344         104 :                 php_end_ob_buffer(send_buffer, 0 TSRMLS_CC);
     345             :         }
     346       19390 : }
     347             : /* }}} */
     348             : 
     349             : /* {{{ php_start_implicit_flush
     350             :  */
     351       18989 : PHPAPI void php_start_implicit_flush(TSRMLS_D)
     352             : {
     353       18989 :         OG(implicit_flush) = 1;
     354       18989 : }
     355             : /* }}} */
     356             : 
     357             : /* {{{ php_end_implicit_flush
     358             :  */
     359           8 : PHPAPI void php_end_implicit_flush(TSRMLS_D)
     360             : {
     361           8 :         OG(implicit_flush) = 0;
     362           8 : }
     363             : /* }}} */
     364             : 
     365             : /* {{{ char *php_get_output_start_filename(TSRMLS_D)
     366             :  *  Return filename start output something */
     367         561 : PHPAPI char *php_get_output_start_filename(TSRMLS_D)
     368             : {
     369         561 :         return OG(output_start_filename);
     370             : }
     371             : /* }}} */
     372             : 
     373             : /* {{{ char *php_get_output_start_lineno(TSRMLS_D)
     374             :  * Return line number start output something */
     375         561 : PHPAPI int php_get_output_start_lineno(TSRMLS_D)
     376             : {
     377         561 :         return OG(output_start_lineno);
     378             : }
     379             : /* }}} */
     380             : 
     381             : /* {{{ php_ob_set_internal_handler
     382             :  */
     383          13 : PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_output_handler, uint buffer_size, char *handler_name, zend_bool erase TSRMLS_DC)
     384             : {
     385          13 :         if (OG(ob_nesting_level) == 0 || OG(active_ob_buffer).internal_output_handler || strcmp(OG(active_ob_buffer).handler_name, OB_DEFAULT_HANDLER_NAME)) {
     386          13 :                 php_start_ob_buffer(NULL, buffer_size, erase TSRMLS_CC);
     387             :         }
     388             : 
     389          13 :         OG(active_ob_buffer).internal_output_handler = internal_output_handler;
     390          13 :         OG(active_ob_buffer).internal_output_handler_buffer = (char *) emalloc(buffer_size);
     391          13 :         OG(active_ob_buffer).internal_output_handler_buffer_size = buffer_size;
     392          13 :         if (OG(active_ob_buffer).handler_name) {
     393          13 :                 efree(OG(active_ob_buffer).handler_name);
     394             :         }
     395          13 :         OG(active_ob_buffer).handler_name = estrdup(handler_name);
     396          13 :         OG(active_ob_buffer).erase = erase;
     397          13 : }
     398             : /* }}} */
     399             : 
     400             : /*
     401             :  * Output buffering - implementation
     402             :  */
     403             : 
     404             : /* {{{ php_ob_allocate
     405             :  */
     406      715534 : static inline void php_ob_allocate(uint text_length TSRMLS_DC)
     407             : {
     408      715534 :         uint new_len = OG(active_ob_buffer).text_length + text_length;
     409             : 
     410      715534 :         if (OG(active_ob_buffer).size < new_len) {
     411          20 :                 uint buf_size = OG(active_ob_buffer).size;
     412          62 :                 while (buf_size <= new_len) {
     413          22 :                         buf_size += OG(active_ob_buffer).block_size;
     414             :                 }
     415             : 
     416          20 :                 OG(active_ob_buffer).buffer = (char *) erealloc(OG(active_ob_buffer).buffer, buf_size+1);
     417          20 :                 OG(active_ob_buffer).size = buf_size;
     418             :         }
     419      715534 :         OG(active_ob_buffer).text_length = new_len;
     420      715534 : }
     421             : /* }}} */
     422             : 
     423             : /* {{{ php_ob_init_conflict
     424             :  * Returns 1 if handler_set is already used and generates error message */
     425           1 : PHPAPI int php_ob_init_conflict(char *handler_new, char *handler_set TSRMLS_DC)
     426             : {
     427           1 :         if (php_ob_handler_used(handler_set TSRMLS_CC)) {
     428           1 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler '%s' conflicts with '%s'", handler_new, handler_set);
     429           1 :                 return 1;
     430             :         }
     431           0 :         return 0;
     432             : }
     433             : /* }}} */
     434             : 
     435             : /* {{{ php_ob_init_named
     436             :  */
     437        4904 : static int php_ob_init_named(uint initial_size, uint block_size, char *handler_name, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
     438             : {
     439             :         php_ob_buffer tmp_buf;
     440             : 
     441        4904 :         if (output_handler && !zend_is_callable(output_handler, 0, NULL TSRMLS_CC)) {
     442           6 :                 return FAILURE;
     443             :         }
     444             : 
     445        4898 :         tmp_buf.block_size = block_size;
     446        4898 :         tmp_buf.size = initial_size;
     447        4898 :         tmp_buf.buffer = (char *) emalloc(initial_size+1);
     448        4898 :         tmp_buf.text_length = 0;
     449        4898 :         tmp_buf.output_handler = output_handler;
     450        4898 :         tmp_buf.chunk_size = chunk_size;
     451        4898 :         tmp_buf.status = 0;
     452        4898 :         tmp_buf.internal_output_handler = NULL;
     453        4898 :         tmp_buf.internal_output_handler_buffer = NULL;
     454        4898 :         tmp_buf.internal_output_handler_buffer_size = 0;
     455        4898 :         tmp_buf.handler_name = estrdup(handler_name&&handler_name[0]?handler_name:OB_DEFAULT_HANDLER_NAME);
     456        4898 :         tmp_buf.erase = erase;
     457             : 
     458        4898 :         if (OG(ob_nesting_level)>0) {
     459             : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
     460         319 :                 if (!strncmp(handler_name, "ob_gzhandler", sizeof("ob_gzhandler")) && php_ob_gzhandler_check(TSRMLS_C)) {
     461           1 :                         return FAILURE;
     462             :                 }
     463             : #endif
     464         318 :                 if (OG(ob_nesting_level)==1) { /* initialize stack */
     465         308 :                         zend_stack_init(&OG(ob_buffers));
     466             :                 }
     467         318 :                 zend_stack_push(&OG(ob_buffers), &OG(active_ob_buffer), sizeof(php_ob_buffer));
     468             :         }
     469        4897 :         OG(ob_nesting_level)++;
     470        4897 :         OG(active_ob_buffer) = tmp_buf;
     471        4897 :         OG(php_body_write) = php_b_body_write;
     472        4897 :         return SUCCESS;
     473             : }
     474             : /* }}} */
     475             : 
     476             : /* {{{ php_ob_handler_from_string
     477             :  * Create zval output handler from string */
     478          94 : static zval* php_ob_handler_from_string(const char *handler_name, int len TSRMLS_DC)
     479             : {
     480             :         zval *output_handler;
     481             : 
     482          94 :         ALLOC_INIT_ZVAL(output_handler);
     483          94 :         Z_STRLEN_P(output_handler) = len;
     484          94 :         Z_STRVAL_P(output_handler) = estrndup(handler_name, len);
     485          94 :         Z_TYPE_P(output_handler) = IS_STRING;
     486          94 :         return output_handler;
     487             : }
     488             : /* }}} */
     489             : 
     490             : /* {{{ php_ob_init
     491             :  */
     492        4917 : static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
     493             : {
     494        4917 :         int result = FAILURE, handler_len, len;
     495             :         char *handler_name, *next_handler_name;
     496             :         HashPosition pos;
     497             :         zval **tmp;
     498             :         zval *handler_zval;
     499             : 
     500        5011 :         if (output_handler && output_handler->type == IS_STRING) {
     501          94 :                 handler_name = Z_STRVAL_P(output_handler);
     502          94 :                 handler_len  = Z_STRLEN_P(output_handler);
     503             : 
     504          94 :                 result = SUCCESS;
     505          94 :                 if (handler_len && handler_name[0] != '\0') {
     506         186 :                         while ((next_handler_name=strchr(handler_name, ',')) != NULL) {
     507           0 :                                 len = next_handler_name-handler_name;
     508           0 :                                 next_handler_name = estrndup(handler_name, len);
     509           0 :                                 handler_zval = php_ob_handler_from_string(next_handler_name, len TSRMLS_CC);
     510           0 :                                 result = php_ob_init_named(initial_size, block_size, next_handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
     511           0 :                                 if (result != SUCCESS) {
     512           0 :                                         zval_dtor(handler_zval);
     513           0 :                                         FREE_ZVAL(handler_zval);
     514             :                                 }
     515           0 :                                 handler_name += len+1;
     516           0 :                                 handler_len -= len+1;
     517           0 :                                 efree(next_handler_name);
     518             :                         }
     519             :                 }
     520          94 :                 if (result == SUCCESS) {
     521          94 :                         handler_zval = php_ob_handler_from_string(handler_name, handler_len TSRMLS_CC);
     522          94 :                         result = php_ob_init_named(initial_size, block_size, handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
     523          94 :                         if (result != SUCCESS) {
     524           7 :                                 zval_dtor(handler_zval);
     525           7 :                                 FREE_ZVAL(handler_zval);
     526             :                         }
     527             :                 }
     528        4839 :         } else if (output_handler && output_handler->type == IS_ARRAY) {
     529             :                 /* do we have array(object,method) */
     530          18 :                 if (zend_is_callable(output_handler, 0, &handler_name TSRMLS_CC)) {
     531          14 :                         SEPARATE_ZVAL(&output_handler);
     532           7 :                         Z_ADDREF_P(output_handler);
     533           7 :                         result = php_ob_init_named(initial_size, block_size, handler_name, output_handler, chunk_size, erase TSRMLS_CC);
     534           7 :                         efree(handler_name);
     535             :                 } else {
     536          11 :                         efree(handler_name);
     537             :                         /* init all array elements recursively */
     538          11 :                         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(output_handler), &pos);
     539          36 :                         while (zend_hash_get_current_data_ex(Z_ARRVAL_P(output_handler), (void **)&tmp, &pos) == SUCCESS) {
     540          20 :                                 result = php_ob_init(initial_size, block_size, *tmp, chunk_size, erase TSRMLS_CC);
     541          18 :                                 if (result == FAILURE) {
     542           4 :                                         break;
     543             :                                 }
     544          14 :                                 zend_hash_move_forward_ex(Z_ARRVAL_P(output_handler), &pos);
     545             :                         }
     546             :                 }
     547        4808 :         } else if (output_handler && output_handler->type == IS_OBJECT) {
     548             :                 /* do we have callable object */
     549           5 :                 if (zend_is_callable(output_handler, 0, &handler_name TSRMLS_CC)) {
     550           6 :                         SEPARATE_ZVAL(&output_handler);
     551           3 :                         Z_ADDREF_P(output_handler);
     552           3 :                         result = php_ob_init_named(initial_size, block_size, handler_name, output_handler, chunk_size, erase TSRMLS_CC);
     553           3 :                         efree(handler_name);
     554             :                 } else {
     555           0 :                         efree(handler_name);
     556           0 :                         php_error_docref(NULL TSRMLS_CC, E_ERROR, "No method name given: use ob_start(array($object,'method')) to specify instance $object and the name of a method of class %s to use as output handler", Z_OBJCE_P(output_handler)->name);
     557           0 :                         result = FAILURE;
     558             :                 }
     559             :         } else {
     560        4800 :                 result = php_ob_init_named(initial_size, block_size, OB_DEFAULT_HANDLER_NAME, NULL, chunk_size, erase TSRMLS_CC);
     561             :         }
     562        4913 :         return result;
     563             : }
     564             : /* }}} */
     565             : 
     566             : /* {{{ php_ob_list_each
     567             :  */
     568          25 : static int php_ob_list_each(php_ob_buffer *ob_buffer, zval *ob_handler_array)
     569             : {
     570          25 :         add_next_index_string(ob_handler_array, ob_buffer->handler_name, 1);
     571          25 :         return 0;
     572             : }
     573             : /* }}} */
     574             : 
     575             : /* {{{ php_ob_used_each
     576             :    Sets handler_name to NULL is found */
     577           0 : static int php_ob_handler_used_each(php_ob_buffer *ob_buffer, char **handler_name)
     578             : {
     579           0 :         if (!strcmp(ob_buffer->handler_name, *handler_name)) {
     580           0 :                 *handler_name = NULL;
     581           0 :                 return 1;
     582             :         }
     583           0 :         return 0;
     584             : }
     585             : /* }}} */
     586             : 
     587             : /* {{{ php_ob_used
     588             :    returns 1 if given handler_name is used as output_handler */
     589           4 : PHPAPI int php_ob_handler_used(char *handler_name TSRMLS_DC)
     590             : {
     591           4 :         char *tmp = handler_name;
     592             : 
     593           4 :         if (OG(ob_nesting_level)) {
     594           4 :                 if (!strcmp(OG(active_ob_buffer).handler_name, handler_name)) {
     595           1 :                         return 1;
     596             :                 }
     597           3 :                 if (OG(ob_nesting_level)>1) {
     598           0 :                         zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *element, void *)) php_ob_handler_used_each, &tmp);
     599             :                 }
     600             :         }
     601           3 :         return tmp ? 0 : 1;
     602             : }
     603             : /* }}} */
     604             : 
     605             : /* {{{ php_ob_append
     606             :  */
     607      715534 : static inline void php_ob_append(const char *text, uint text_length TSRMLS_DC)
     608             : {
     609             :         char *target;
     610             :         uint original_ob_text_length;
     611             : 
     612      715534 :         original_ob_text_length=OG(active_ob_buffer).text_length;
     613             : 
     614      715534 :         php_ob_allocate(text_length TSRMLS_CC);
     615      715534 :         target = OG(active_ob_buffer).buffer+original_ob_text_length;
     616      715534 :         memcpy(target, text, text_length);
     617      715534 :         target[text_length]=0;
     618             : 
     619             :         /* If implicit_flush is On or chunked buffering, send contents to next buffer and return. */
     620     1401071 :         if (OG(active_ob_buffer).chunk_size
     621     1401071 :                 && OG(active_ob_buffer).text_length >= OG(active_ob_buffer).chunk_size) {
     622             : 
     623        1208 :                 php_end_ob_buffer(1, 1 TSRMLS_CC);
     624        1208 :                 return;
     625             :         }
     626             : }
     627             : /* }}} */
     628             : 
     629             : #if 0
     630             : static inline void php_ob_prepend(const char *text, uint text_length)
     631             : {
     632             :         char *p, *start;
     633             :         TSRMLS_FETCH();
     634             : 
     635             :         php_ob_allocate(text_length TSRMLS_CC);
     636             : 
     637             :         /* php_ob_allocate() may change OG(ob_buffer), so we can't initialize p&start earlier */
     638             :         p = OG(ob_buffer)+OG(ob_text_length);
     639             :         start = OG(ob_buffer);
     640             : 
     641             :         while (--p>=start) {
     642             :                 p[text_length] = *p;
     643             :         }
     644             :         memcpy(OG(ob_buffer), text, text_length);
     645             :         OG(ob_buffer)[OG(active_ob_buffer).text_length]=0;
     646             : }
     647             : #endif
     648             : 
     649             : /* {{{ php_ob_get_buffer
     650             :  * Return the current output buffer */
     651        3909 : PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC)
     652             : {
     653        3909 :         if (OG(ob_nesting_level)==0) {
     654           7 :                 return FAILURE;
     655             :         }
     656        3902 :         ZVAL_STRINGL(p, OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length, 1);
     657        3902 :         return SUCCESS;
     658             : }
     659             : /* }}} */
     660             : 
     661             : /* {{{ php_ob_get_length
     662             :  * Return the size of the current output buffer */
     663          23 : PHPAPI int php_ob_get_length(zval *p TSRMLS_DC)
     664             : {
     665          23 :         if (OG(ob_nesting_level) == 0) {
     666           4 :                 return FAILURE;
     667             :         }
     668          19 :         ZVAL_LONG(p, OG(active_ob_buffer).text_length);
     669          19 :         return SUCCESS;
     670             : }
     671             : /* }}} */
     672             : 
     673             : /*
     674             :  * Wrapper functions - implementation
     675             :  */
     676             : 
     677             : /* buffered output function */
     678      715534 : static int php_b_body_write(const char *str, uint str_length TSRMLS_DC)
     679             : {
     680      715534 :         php_ob_append(str, str_length TSRMLS_CC);
     681      715534 :         return str_length;
     682             : }
     683             : 
     684             : /* {{{ php_ub_body_write_no_header
     685             :  */
     686      889021 : PHPAPI int php_ub_body_write_no_header(const char *str, uint str_length TSRMLS_DC)
     687             : {
     688             :         int result;
     689             : 
     690      889021 :         if (OG(disable_output)) {
     691           0 :                 return 0;
     692             :         }
     693             : 
     694      889021 :         result = OG(php_header_write)(str, str_length TSRMLS_CC);
     695             : 
     696      889019 :         if (OG(implicit_flush)) {
     697      884683 :                 sapi_flush(TSRMLS_C);
     698             :         }
     699             : 
     700      889019 :         return result;
     701             : }
     702             : /* }}} */
     703             : 
     704             : /* {{{ php_ub_body_write
     705             :  */
     706       12661 : PHPAPI int php_ub_body_write(const char *str, uint str_length TSRMLS_DC)
     707             : {
     708       12661 :         int result = 0;
     709             : 
     710       12661 :         if (SG(request_info).headers_only) {
     711           0 :                 if(SG(headers_sent)) {
     712           0 :                         return 0;
     713             :                 }
     714           0 :                 php_header(TSRMLS_C);
     715           0 :                 zend_bailout();
     716             :         }
     717       12661 :         if (php_header(TSRMLS_C)) {
     718       12661 :                 if (zend_is_compiling(TSRMLS_C)) {
     719         207 :                         OG(output_start_filename) = zend_get_compiled_filename(TSRMLS_C);
     720         207 :                         OG(output_start_lineno) = zend_get_compiled_lineno(TSRMLS_C);
     721       12454 :                 } else if (zend_is_executing(TSRMLS_C)) {
     722       12265 :                         OG(output_start_filename) = zend_get_executed_filename(TSRMLS_C);
     723       12265 :                         OG(output_start_lineno) = zend_get_executed_lineno(TSRMLS_C);
     724             :                 }
     725             : 
     726       12661 :                 OG(php_body_write) = php_ub_body_write_no_header;
     727       12661 :                 result = php_ub_body_write_no_header(str, str_length TSRMLS_CC);
     728             :         }
     729             : 
     730       12659 :         return result;
     731             : }
     732             : /* }}} */
     733             : 
     734             : /* {{{ int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result)
     735             :  */
     736           6 : static int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result)
     737             : {
     738             :         zval *elem;
     739             : 
     740           6 :         MAKE_STD_ZVAL(elem);
     741           6 :         array_init(elem);
     742             : 
     743           6 :         add_assoc_long(elem, "chunk_size", ob_buffer->chunk_size);
     744           6 :         if (!ob_buffer->chunk_size) {
     745           6 :                 add_assoc_long(elem, "size", ob_buffer->size);
     746           6 :                 add_assoc_long(elem, "block_size", ob_buffer->block_size);
     747             :         }
     748           6 :         if (ob_buffer->internal_output_handler) {
     749           0 :                 add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_INTERNAL);
     750           0 :                 add_assoc_long(elem, "buffer_size", ob_buffer->internal_output_handler_buffer_size);
     751             :         } else {
     752           6 :                 add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_USER);
     753             :         }
     754           6 :         add_assoc_long(elem, "status", ob_buffer->status);
     755           6 :         add_assoc_string(elem, "name", ob_buffer->handler_name, 1);
     756           6 :         add_assoc_bool(elem, "del", ob_buffer->erase);
     757           6 :         add_next_index_zval(result, elem);
     758             : 
     759           6 :         return SUCCESS;
     760             : }
     761             : /* }}} */
     762             : 
     763             : /*
     764             :  * USERLAND (nearly 1:1 of old output.c)
     765             :  */
     766             : 
     767             : /* {{{ proto bool ob_start([string|array user_function [, int chunk_size [, bool erase]]])
     768             :    Turn on Output Buffering (specifying an optional output handler). */
     769        4116 : PHP_FUNCTION(ob_start)
     770             : {
     771        4116 :         zval *output_handler = NULL;
     772        4116 :         long chunk_size = 0;
     773        4116 :         zend_bool erase = 1;
     774             : 
     775        4116 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/lb", &output_handler, &chunk_size, &erase) == FAILURE) {
     776           2 :                 return;
     777             :         }
     778             : 
     779        4114 :         if (chunk_size < 0) {
     780           2 :                 chunk_size = 0;
     781             :         }
     782             : 
     783        4114 :         if (php_start_ob_buffer(output_handler, chunk_size, erase TSRMLS_CC) == FAILURE) {
     784           7 :                 RETURN_FALSE;
     785             :         }
     786        4104 :         RETURN_TRUE;
     787             : }
     788             : /* }}} */
     789             : 
     790             : /* {{{ proto bool ob_flush(void)
     791             :    Flush (send) contents of the output buffer. The last buffer content is sent to next buffer */
     792          22 : PHP_FUNCTION(ob_flush)
     793             : {
     794          22 :         if (zend_parse_parameters_none() == FAILURE) {
     795           1 :                 return;
     796             :         }
     797             : 
     798          21 :         if (!OG(ob_nesting_level)) {
     799           1 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to flush buffer. No buffer to flush");
     800           1 :                 RETURN_FALSE;
     801             :         }
     802             : 
     803          20 :         if (!OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
     804           2 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to flush buffer %s", OG(active_ob_buffer).handler_name);
     805           2 :                 RETURN_FALSE;
     806             :         }
     807             : 
     808          18 :         php_end_ob_buffer(1, 1 TSRMLS_CC);
     809          18 :         RETURN_TRUE;
     810             : }
     811             : /* }}} */
     812             : 
     813             : /* {{{ proto bool ob_clean(void)
     814             :    Clean (delete) the current output buffer */
     815          12 : PHP_FUNCTION(ob_clean)
     816             : {
     817          12 :         if (zend_parse_parameters_none() == FAILURE) {
     818           1 :                 return;
     819             :         }
     820             : 
     821          11 :         if (!OG(ob_nesting_level)) {
     822           3 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
     823           3 :                 RETURN_FALSE;
     824             :         }
     825             : 
     826           8 :         if (!OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
     827           1 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
     828           1 :                 RETURN_FALSE;
     829             :         }
     830             : 
     831           7 :         php_end_ob_buffer(0, 1 TSRMLS_CC);
     832           7 :         RETURN_TRUE;
     833             : }
     834             : /* }}} */
     835             : 
     836             : /* {{{ proto bool ob_end_flush(void)
     837             :    Flush (send) the output buffer, and delete current output buffer */
     838         207 : PHP_FUNCTION(ob_end_flush)
     839             : {
     840         207 :         if (zend_parse_parameters_none() == FAILURE) {
     841           1 :                 return;
     842             :         }
     843             : 
     844         206 :         if (!OG(ob_nesting_level)) {
     845           4 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush");
     846           4 :                 RETURN_FALSE;
     847             :         }
     848             : 
     849         202 :         if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
     850           1 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
     851           1 :                 RETURN_FALSE;
     852             :         }
     853             : 
     854         201 :         php_end_ob_buffer(1, 0 TSRMLS_CC);
     855         201 :         RETURN_TRUE;
     856             : }
     857             : /* }}} */
     858             : 
     859             : /* {{{ proto bool ob_end_clean(void)
     860             :    Clean the output buffer, and delete current output buffer */
     861         254 : PHP_FUNCTION(ob_end_clean)
     862             : {
     863         254 :         if (zend_parse_parameters_none() == FAILURE) {
     864           1 :                 return;
     865             :         }
     866             : 
     867         253 :         if (!OG(ob_nesting_level)) {
     868           4 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
     869           4 :                 RETURN_FALSE;
     870             :         }
     871             : 
     872         249 :         if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
     873           1 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
     874           1 :                 RETURN_FALSE;
     875             :         }
     876             : 
     877         248 :         php_end_ob_buffer(0, 0 TSRMLS_CC);
     878         248 :         RETURN_TRUE;
     879             : }
     880             : /* }}} */
     881             : 
     882             : /* {{{ proto bool ob_get_flush(void)
     883             :    Get current buffer contents, flush (send) the output buffer, and delete current output buffer */
     884           7 : PHP_FUNCTION(ob_get_flush)
     885             : {
     886           7 :         if (zend_parse_parameters_none() == FAILURE) {
     887           1 :                 return;
     888             :         }
     889             : 
     890           6 :         if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) {
     891           1 :                 RETURN_FALSE;
     892             :         }
     893             : 
     894           5 :         if (!OG(ob_nesting_level)) {
     895           0 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush");
     896           0 :                 zval_dtor(return_value);
     897           0 :                 RETURN_FALSE;
     898             :         }
     899             : 
     900           5 :         if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
     901           1 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
     902           1 :                 zval_dtor(return_value);
     903           1 :                 RETURN_FALSE;
     904             :         }
     905             : 
     906           4 :         php_end_ob_buffer(1, 0 TSRMLS_CC);
     907             : }
     908             : /* }}} */
     909             : 
     910             : /* {{{ proto bool ob_get_clean(void)
     911             :    Get current buffer contents and delete current output buffer */
     912        3605 : PHP_FUNCTION(ob_get_clean)
     913             : {
     914        3605 :         if (zend_parse_parameters_none() == FAILURE) {
     915           1 :                 return;
     916             :         }
     917             : 
     918        3604 :         if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) {
     919           1 :                 RETURN_FALSE;
     920             :         }
     921             : 
     922        3603 :         if (!OG(ob_nesting_level)) {
     923           0 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
     924           0 :                 zval_dtor(return_value);
     925           0 :                 RETURN_FALSE;
     926             :         }
     927        3603 :         if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
     928           1 :                 php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
     929           1 :                 zval_dtor(return_value);
     930           1 :                 RETURN_FALSE;
     931             :         }
     932             : 
     933        3602 :         php_end_ob_buffer(0, 0 TSRMLS_CC);
     934             : }
     935             : /* }}} */
     936             : 
     937             : /* {{{ proto string ob_get_contents(void)
     938             :    Return the contents of the output buffer */
     939         159 : PHP_FUNCTION(ob_get_contents)
     940             : {
     941         159 :         if (zend_parse_parameters_none() == FAILURE) {
     942           2 :                 return;
     943             :         }
     944             : 
     945         157 :         if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) {
     946           5 :                 RETURN_FALSE;
     947             :         }
     948             : }
     949             : /* }}} */
     950             : 
     951             : /* {{{ proto int ob_get_level(void)
     952             :    Return the nesting level of the output buffer */
     953          37 : PHP_FUNCTION(ob_get_level)
     954             : {
     955          37 :         if (zend_parse_parameters_none() == FAILURE) {
     956           1 :                 return;
     957             :         }
     958             : 
     959          36 :         RETURN_LONG(OG(ob_nesting_level));
     960             : }
     961             : /* }}} */
     962             : 
     963             : /* {{{ proto int ob_get_length(void)
     964             :    Return the length of the output buffer */
     965          15 : PHP_FUNCTION(ob_get_length)
     966             : {
     967          15 :         if (zend_parse_parameters_none() == FAILURE) {
     968           2 :                 return;
     969             :         }
     970             : 
     971          13 :         if (php_ob_get_length(return_value TSRMLS_CC) == FAILURE) {
     972           3 :                 RETURN_FALSE;
     973             :         }
     974             : }
     975             : /* }}} */
     976             : 
     977             : /* {{{ proto false|array ob_list_handlers()
     978             :    List all output_buffers in an array */
     979          17 : PHP_FUNCTION(ob_list_handlers)
     980             : {
     981          17 :         if (zend_parse_parameters_none() == FAILURE) {
     982           0 :                 return;
     983             :         }
     984             : 
     985          17 :         array_init(return_value);
     986             : 
     987          17 :         if (OG(ob_nesting_level)) {
     988          13 :                 if (OG(ob_nesting_level) > 1) {
     989           5 :                         zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *element, void *)) php_ob_list_each, return_value);
     990             :                 }
     991          13 :                 php_ob_list_each(&OG(active_ob_buffer), return_value);
     992             :         }
     993             : }
     994             : /* }}} */
     995             : 
     996             : /* {{{ proto false|array ob_get_status([bool full_status])
     997             :    Return the status of the active or all output buffers */
     998           3 : PHP_FUNCTION(ob_get_status)
     999             : {
    1000           3 :         zend_bool full_status = 0;
    1001             : 
    1002           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &full_status) == FAILURE) {
    1003           0 :                 return;
    1004             :         }
    1005             : 
    1006           3 :         array_init(return_value);
    1007             : 
    1008           3 :         if (full_status) {
    1009           2 :                 if (OG(ob_nesting_level) > 1) {
    1010           1 :                         zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *elem, void *))php_ob_buffer_status, return_value);
    1011             :                 }
    1012           2 :                 if (OG(ob_nesting_level) > 0 && php_ob_buffer_status(&OG(active_ob_buffer), return_value) == FAILURE) {
    1013           0 :                         RETURN_FALSE;
    1014             :                 }
    1015           1 :         } else if (OG(ob_nesting_level) > 0) {
    1016           1 :                 add_assoc_long(return_value, "level", OG(ob_nesting_level));
    1017           1 :                 if (OG(active_ob_buffer).internal_output_handler) {
    1018           0 :                         add_assoc_long(return_value, "type", PHP_OUTPUT_HANDLER_INTERNAL);
    1019             :                 } else {
    1020           1 :                         add_assoc_long(return_value, "type", PHP_OUTPUT_HANDLER_USER);
    1021             :                 }
    1022           1 :                 add_assoc_long(return_value, "status", OG(active_ob_buffer).status);
    1023           1 :                 add_assoc_string(return_value, "name", OG(active_ob_buffer).handler_name, 1);
    1024           1 :                 add_assoc_bool(return_value, "del", OG(active_ob_buffer).erase);
    1025             :         }
    1026             : }
    1027             : /* }}} */
    1028             : 
    1029             : /* {{{ proto void ob_implicit_flush([int flag])
    1030             :    Turn implicit flush on/off and is equivalent to calling flush() after every output call */
    1031          30 : PHP_FUNCTION(ob_implicit_flush)
    1032             : {
    1033          30 :         long flag = 1;
    1034             : 
    1035          30 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flag) == FAILURE) {
    1036          13 :                 return;
    1037             :         }
    1038             : 
    1039          17 :         if (flag) {
    1040           9 :                 php_start_implicit_flush(TSRMLS_C);
    1041             :         } else {
    1042           8 :                 php_end_implicit_flush(TSRMLS_C);
    1043             :         }
    1044             : }
    1045             : /* }}} */
    1046             : 
    1047             : /* {{{ proto bool output_reset_rewrite_vars(void)
    1048             :    Reset(clear) URL rewriter values */
    1049           1 : PHP_FUNCTION(output_reset_rewrite_vars)
    1050             : {
    1051           1 :         if (php_url_scanner_reset_vars(TSRMLS_C) == SUCCESS) {
    1052           1 :                 RETURN_TRUE;
    1053             :         } else {
    1054           0 :                 RETURN_FALSE;
    1055             :         }
    1056             : }
    1057             : /* }}} */
    1058             : 
    1059             : /* {{{ proto bool output_add_rewrite_var(string name, string value)
    1060             :    Add URL rewriter values */
    1061           3 : PHP_FUNCTION(output_add_rewrite_var)
    1062             : {
    1063             :         char *name, *value;
    1064             :         int name_len, value_len;
    1065             : 
    1066           3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &value, &value_len) == FAILURE) {
    1067           0 :                 return;
    1068             :         }
    1069             : 
    1070           3 :         if (php_url_scanner_add_var(name, name_len, value, value_len, 1 TSRMLS_CC) == SUCCESS) {
    1071           3 :                 RETURN_TRUE;
    1072             :         } else {
    1073           0 :                 RETURN_FALSE;
    1074             :         }
    1075             : }
    1076             : /* }}} */
    1077             : 
    1078             : /*
    1079             :  * Local variables:
    1080             :  * tab-width: 4
    1081             :  * c-basic-offset: 4
    1082             :  * End:
    1083             :  * vim600: sw=4 ts=4 fdm=marker
    1084             :  * vim<600: sw=4 ts=4
    1085             :  */

Generated by: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:41 +0000 (6 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.