2010-05-31 18:29:43 +08:00
/*
1999-10-28 02:30:41 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-09-20 00:33:14 +08:00
| PHP Version 7 |
1999-10-28 02:30:41 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2018-01-02 12:57:58 +08:00
| Copyright ( c ) 1997 - 2018 The PHP Group |
1999-10-28 02:30:41 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
1999-10-28 02:30:41 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
1999-10-28 02:30:41 +08:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-06-07 02:54:00 +08:00
| Authors : Zeev Suraski < zeev @ zend . com > |
2000-10-29 17:14:55 +08:00
| Thies C . Arntzen < thies @ thieso . net > |
2002-08-10 06:29:58 +08:00
| Marcus Boerger < helly @ php . net > |
2010-05-31 18:29:43 +08:00
| New API : Michael Wallner < mike @ php . net > |
1999-10-28 02:30:41 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2000-07-24 09:40:02 +08:00
/* $Id$ */
1999-10-28 02:30:41 +08:00
2010-05-31 18:29:43 +08:00
# ifndef PHP_OUTPUT_DEBUG
# define PHP_OUTPUT_DEBUG 0
# endif
# ifndef PHP_OUTPUT_NOINLINE
# define PHP_OUTPUT_NOINLINE 0
# endif
1999-10-28 02:30:41 +08:00
# include "php.h"
# include "ext/standard/head.h"
2002-05-03 16:00:41 +08:00
# include "ext/standard/url_scanner_ex.h"
2010-03-12 18:28:59 +08:00
# include "SAPI.h"
2010-05-31 18:29:43 +08:00
# include "zend_stack.h"
# include "php_output.h"
1999-10-28 02:30:41 +08:00
2014-10-30 17:27:20 +08:00
PHPAPI ZEND_DECLARE_MODULE_GLOBALS ( output ) ;
2010-03-11 18:24:29 +08:00
2010-06-02 20:49:12 +08:00
const char php_output_default_handler_name [ sizeof ( " default output handler " ) ] = " default output handler " ;
const char php_output_devnull_handler_name [ sizeof ( " null output handler " ) ] = " null output handler " ;
2010-03-11 18:24:29 +08:00
2010-05-31 18:29:43 +08:00
# if PHP_OUTPUT_NOINLINE || PHP_OUTPUT_DEBUG
# undef inline
# define inline
2010-03-12 18:28:59 +08:00
# endif
1999-10-28 02:30:41 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ aliases, conflict and reverse conflict hash tables */
static HashTable php_output_handler_aliases ;
static HashTable php_output_handler_conflicts ;
static HashTable php_output_handler_reverse_conflicts ;
/* }}} */
/* {{{ forward declarations */
2014-12-14 06:06:14 +08:00
static inline int php_output_lock_error ( int op ) ;
static inline void php_output_op ( int op , const char * str , size_t len ) ;
2010-05-31 18:29:43 +08:00
2014-12-14 06:06:14 +08:00
static inline php_output_handler * php_output_handler_init ( zend_string * name , size_t chunk_size , int flags ) ;
2010-05-31 18:29:43 +08:00
static inline php_output_handler_status_t php_output_handler_op ( php_output_handler * handler , php_output_context * context ) ;
2014-12-14 06:06:14 +08:00
static inline int php_output_handler_append ( php_output_handler * handler , const php_output_buffer * buf ) ;
2010-05-31 18:29:43 +08:00
static inline zval * php_output_handler_status ( php_output_handler * handler , zval * entry ) ;
2014-12-14 06:06:14 +08:00
static inline php_output_context * php_output_context_init ( php_output_context * context , int op ) ;
2010-05-31 18:29:43 +08:00
static inline void php_output_context_reset ( php_output_context * context ) ;
static inline void php_output_context_swap ( php_output_context * context ) ;
static inline void php_output_context_dtor ( php_output_context * context ) ;
2014-12-14 06:06:14 +08:00
static inline int php_output_stack_pop ( int flags ) ;
2010-05-31 18:29:43 +08:00
static int php_output_stack_apply_op ( void * h , void * c ) ;
static int php_output_stack_apply_clean ( void * h , void * c ) ;
static int php_output_stack_apply_list ( void * h , void * z ) ;
static int php_output_stack_apply_status ( void * h , void * z ) ;
2010-03-11 18:24:29 +08:00
2010-05-31 18:29:43 +08:00
static int php_output_handler_compat_func ( void * * handler_context , php_output_context * output_context ) ;
static int php_output_handler_default_func ( void * * handler_context , php_output_context * output_context ) ;
static int php_output_handler_devnull_func ( void * * handler_context , php_output_context * output_context ) ;
/* }}} */
/* {{{ static void php_output_init_globals(zend_output_globals *G)
2010-12-03 23:34:24 +08:00
* Initialize the module globals on MINIT */
2010-05-31 18:29:43 +08:00
static inline void php_output_init_globals ( zend_output_globals * G )
2001-05-08 06:00:13 +08:00
{
2015-02-17 00:19:32 +08:00
ZEND_TSRMLS_CACHE_UPDATE ( ) ;
2010-05-31 18:29:43 +08:00
memset ( G , 0 , sizeof ( * G ) ) ;
2001-05-08 06:00:13 +08:00
}
2002-10-03 12:17:41 +08:00
/* }}} */
2001-05-08 06:00:13 +08:00
2012-01-30 20:17:51 +08:00
/* {{{ stderr/stdout writer if not PHP_OUTPUT_ACTIVATED */
2014-10-27 20:08:21 +08:00
static size_t php_output_stdout ( const char * str , size_t str_len )
2012-01-30 20:17:51 +08:00
{
fwrite ( str , 1 , str_len , stdout ) ;
return str_len ;
}
2014-10-27 20:08:21 +08:00
static size_t php_output_stderr ( const char * str , size_t str_len )
2012-01-26 01:22:46 +08:00
{
fwrite ( str , 1 , str_len , stderr ) ;
/* See http://support.microsoft.com/kb/190351 */
# ifdef PHP_WIN32
fflush ( stderr ) ;
# endif
return str_len ;
}
2014-10-27 20:08:21 +08:00
static size_t ( * php_output_direct ) ( const char * str , size_t str_len ) = php_output_stderr ;
2012-01-26 01:22:46 +08:00
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_header(void) */
static void php_output_header ( void )
2012-01-31 16:51:24 +08:00
{
if ( ! SG ( headers_sent ) ) {
if ( ! OG ( output_start_filename ) ) {
2014-12-14 06:06:14 +08:00
if ( zend_is_compiling ( ) ) {
2015-06-30 18:59:27 +08:00
OG ( output_start_filename ) = ZSTR_VAL ( zend_get_compiled_filename ( ) ) ;
2014-12-14 06:06:14 +08:00
OG ( output_start_lineno ) = zend_get_compiled_lineno ( ) ;
} else if ( zend_is_executing ( ) ) {
OG ( output_start_filename ) = zend_get_executed_filename ( ) ;
OG ( output_start_lineno ) = zend_get_executed_lineno ( ) ;
2012-01-31 16:51:24 +08:00
}
# if PHP_OUTPUT_DEBUG
fprintf ( stderr , " !!! output started at: %s (%d) \n " , OG ( output_start_filename ) , OG ( output_start_lineno ) ) ;
# endif
}
2014-12-14 06:06:14 +08:00
if ( ! php_header ( ) ) {
2012-01-31 16:51:24 +08:00
OG ( flags ) | = PHP_OUTPUT_DISABLED ;
}
}
}
/* }}} */
2014-02-10 14:04:30 +08:00
static void reverse_conflict_dtor ( zval * zv )
{
HashTable * ht = Z_PTR_P ( zv ) ;
zend_hash_destroy ( ht ) ;
}
2010-05-31 18:29:43 +08:00
/* {{{ void php_output_startup(void)
2010-12-03 23:34:24 +08:00
* Set up module globals and initalize the conflict and reverse conflict hash tables */
2010-05-31 18:29:43 +08:00
PHPAPI void php_output_startup ( void )
1999-10-28 02:30:41 +08:00
{
2010-05-31 18:29:43 +08:00
ZEND_INIT_MODULE_GLOBALS ( output , php_output_init_globals , NULL ) ;
2014-04-21 22:25:34 +08:00
zend_hash_init ( & php_output_handler_aliases , 8 , NULL , NULL , 1 ) ;
zend_hash_init ( & php_output_handler_conflicts , 8 , NULL , NULL , 1 ) ;
zend_hash_init ( & php_output_handler_reverse_conflicts , 8 , NULL , reverse_conflict_dtor , 1 ) ;
2012-01-30 20:17:51 +08:00
php_output_direct = php_output_stdout ;
1999-10-28 02:30:41 +08:00
}
2002-10-03 12:17:41 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ void php_output_shutdown(void)
2010-12-03 23:34:24 +08:00
* Destroy module globals and the conflict and reverse conflict hash tables */
2010-05-31 18:29:43 +08:00
PHPAPI void php_output_shutdown ( void )
{
2012-01-30 20:17:51 +08:00
php_output_direct = php_output_stderr ;
2010-05-31 18:29:43 +08:00
zend_hash_destroy ( & php_output_handler_aliases ) ;
zend_hash_destroy ( & php_output_handler_conflicts ) ;
zend_hash_destroy ( & php_output_handler_reverse_conflicts ) ;
}
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_activate(void)
2010-12-03 23:34:24 +08:00
* Reset output globals and setup the output handler stack */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_activate ( void )
1999-10-28 02:30:41 +08:00
{
# ifdef ZTS
2014-10-15 22:33:40 +08:00
memset ( ( * ( ( void * * * ) ZEND_TSRMLS_CACHE ) ) [ TSRM_UNSHUFFLE_RSRC_ID ( output_globals_id ) ] , 0 , sizeof ( zend_output_globals ) ) ;
2010-05-31 18:29:43 +08:00
# else
memset ( & output_globals , 0 , sizeof ( zend_output_globals ) ) ;
1999-10-28 02:30:41 +08:00
# endif
2010-12-03 23:34:24 +08:00
2014-05-01 02:28:02 +08:00
zend_stack_init ( & OG ( handlers ) , sizeof ( php_output_handler * ) ) ;
2012-01-26 01:22:46 +08:00
OG ( flags ) | = PHP_OUTPUT_ACTIVATED ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return SUCCESS ;
2001-07-03 02:17:10 +08:00
}
2002-10-03 12:17:41 +08:00
/* }}} */
2001-07-03 02:17:10 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_deactivate(void)
2010-12-03 23:34:24 +08:00
* Destroy the output handler stack */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_deactivate ( void )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
php_output_handler * * handler = NULL ;
2010-12-03 23:34:24 +08:00
2015-02-18 20:58:31 +08:00
if ( ( OG ( flags ) & PHP_OUTPUT_ACTIVATED ) ) {
2015-02-19 17:50:03 +08:00
php_output_header ( ) ;
2012-01-31 16:51:24 +08:00
2015-02-18 20:58:31 +08:00
OG ( flags ) ^ = PHP_OUTPUT_ACTIVATED ;
OG ( active ) = NULL ;
OG ( running ) = NULL ;
2010-12-03 23:34:24 +08:00
2015-02-18 20:58:31 +08:00
/* release all output handlers */
if ( OG ( handlers ) . elements ) {
2015-02-18 21:04:19 +08:00
while ( ( handler = zend_stack_top ( & OG ( handlers ) ) ) ) {
php_output_handler_free ( handler ) ;
2015-02-18 20:58:31 +08:00
zend_stack_del_top ( & OG ( handlers ) ) ;
}
2010-05-31 18:29:43 +08:00
}
2010-08-27 14:09:18 +08:00
zend_stack_destroy ( & OG ( handlers ) ) ;
2010-05-31 18:29:43 +08:00
}
2010-03-11 18:24:29 +08:00
}
/* }}} */
2001-07-20 21:59:00 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ void php_output_register_constants() */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_register_constants ( void )
2001-03-04 09:45:19 +08:00
{
2014-08-26 01:24:55 +08:00
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_START " , PHP_OUTPUT_HANDLER_START , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_WRITE " , PHP_OUTPUT_HANDLER_WRITE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_FLUSH " , PHP_OUTPUT_HANDLER_FLUSH , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_CLEAN " , PHP_OUTPUT_HANDLER_CLEAN , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_FINAL " , PHP_OUTPUT_HANDLER_FINAL , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_CONT " , PHP_OUTPUT_HANDLER_WRITE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_END " , PHP_OUTPUT_HANDLER_FINAL , CONST_CS | CONST_PERSISTENT ) ;
2010-05-31 18:29:43 +08:00
2014-08-26 01:24:55 +08:00
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_CLEANABLE " , PHP_OUTPUT_HANDLER_CLEANABLE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_FLUSHABLE " , PHP_OUTPUT_HANDLER_FLUSHABLE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_REMOVABLE " , PHP_OUTPUT_HANDLER_REMOVABLE , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_STDFLAGS " , PHP_OUTPUT_HANDLER_STDFLAGS , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_STARTED " , PHP_OUTPUT_HANDLER_STARTED , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_MAIN_LONG_CONSTANT ( " PHP_OUTPUT_HANDLER_DISABLED " , PHP_OUTPUT_HANDLER_DISABLED , CONST_CS | CONST_PERSISTENT ) ;
1999-10-28 02:30:41 +08:00
}
2002-10-03 12:17:41 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_set_status(int status)
2010-12-03 23:34:24 +08:00
* Used by SAPIs to disable output */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_set_status ( int status )
2010-03-11 18:24:29 +08:00
{
2012-09-10 18:54:18 +08:00
OG ( flags ) = ( OG ( flags ) & ~ 0xf ) | ( status & 0xf ) ;
2010-03-11 18:24:29 +08:00
}
/* }}} */
2001-03-04 09:45:19 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ int php_output_get_status()
2010-12-03 23:34:24 +08:00
* Get output control status */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_get_status ( void )
1999-10-28 02:30:41 +08:00
{
2012-01-26 01:22:46 +08:00
return (
OG ( flags )
| ( OG ( active ) ? PHP_OUTPUT_ACTIVE : 0 )
| ( OG ( running ) ? PHP_OUTPUT_LOCKED : 0 )
) & 0xff ;
1999-10-28 02:30:41 +08:00
}
2002-10-03 12:17:41 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ int php_output_write_unbuffered(const char *str, size_t len)
2010-12-03 23:34:24 +08:00
* Unbuffered write */
2014-12-14 06:06:14 +08:00
PHPAPI size_t php_output_write_unbuffered ( const char * str , size_t len )
1999-10-28 02:30:41 +08:00
{
2012-01-26 01:22:46 +08:00
if ( OG ( flags ) & PHP_OUTPUT_ACTIVATED ) {
2014-12-14 06:06:14 +08:00
return sapi_module . ub_write ( str , len ) ;
2012-01-26 01:22:46 +08:00
}
2012-01-30 20:17:51 +08:00
return php_output_direct ( str , len ) ;
2010-03-11 18:24:29 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ int php_output_write(const char *str, size_t len)
2010-12-03 23:34:24 +08:00
* Buffered write */
2014-12-14 06:06:14 +08:00
PHPAPI size_t php_output_write ( const char * str , size_t len )
2010-03-11 18:24:29 +08:00
{
2012-01-26 01:22:46 +08:00
if ( OG ( flags ) & PHP_OUTPUT_ACTIVATED ) {
2014-12-14 06:06:14 +08:00
php_output_op ( PHP_OUTPUT_HANDLER_WRITE , str , len ) ;
2014-10-27 20:08:21 +08:00
return len ;
2012-01-26 01:22:46 +08:00
}
2015-03-25 22:22:37 +08:00
if ( OG ( flags ) & PHP_OUTPUT_DISABLED ) {
return 0 ;
}
2012-01-30 20:17:51 +08:00
return php_output_direct ( str , len ) ;
2010-05-31 18:29:43 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_flush(void)
2010-12-03 23:34:24 +08:00
* Flush the most recent output handlers buffer */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_flush ( void )
2010-05-31 18:29:43 +08:00
{
php_output_context context ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( OG ( active ) & & ( OG ( active ) - > flags & PHP_OUTPUT_HANDLER_FLUSHABLE ) ) {
2014-12-14 06:06:14 +08:00
php_output_context_init ( & context , PHP_OUTPUT_HANDLER_FLUSH ) ;
2010-05-31 18:29:43 +08:00
php_output_handler_op ( OG ( active ) , & context ) ;
if ( context . out . data & & context . out . used ) {
2010-08-27 14:09:18 +08:00
zend_stack_del_top ( & OG ( handlers ) ) ;
2014-12-14 06:06:14 +08:00
php_output_write ( context . out . data , context . out . used ) ;
2014-05-01 02:28:02 +08:00
zend_stack_push ( & OG ( handlers ) , & OG ( active ) ) ;
2010-03-12 18:28:59 +08:00
}
2010-05-31 18:29:43 +08:00
php_output_context_dtor ( & context ) ;
return SUCCESS ;
2010-03-11 18:24:29 +08:00
}
2010-05-31 18:29:43 +08:00
return FAILURE ;
1999-10-28 02:30:41 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_flush_all()
2010-12-03 23:34:24 +08:00
* Flush all output buffers subsequently */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_flush_all ( void )
1999-10-28 02:30:41 +08:00
{
2010-05-31 18:29:43 +08:00
if ( OG ( active ) ) {
2014-12-14 06:06:14 +08:00
php_output_op ( PHP_OUTPUT_HANDLER_FLUSH , NULL , 0 ) ;
2010-05-31 18:29:43 +08:00
}
2010-03-11 18:24:29 +08:00
}
/* }}} */
2000-09-03 02:03:58 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_clean(void)
2010-12-03 23:34:24 +08:00
* Cleans the most recent output handlers buffer if the handler is cleanable */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_clean ( void )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
php_output_context context ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( OG ( active ) & & ( OG ( active ) - > flags & PHP_OUTPUT_HANDLER_CLEANABLE ) ) {
2014-12-14 06:06:14 +08:00
php_output_context_init ( & context , PHP_OUTPUT_HANDLER_CLEAN ) ;
2010-05-31 18:29:43 +08:00
php_output_handler_op ( OG ( active ) , & context ) ;
php_output_context_dtor ( & context ) ;
return SUCCESS ;
}
return FAILURE ;
}
/* }}} */
2000-11-03 00:46:30 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_clean_all(void)
2010-12-03 23:34:24 +08:00
* Cleans all output handler buffers , without regard whether the handler is cleanable */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_clean_all ( void )
2010-05-31 18:29:43 +08:00
{
php_output_context context ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( OG ( active ) ) {
2014-12-14 06:06:14 +08:00
php_output_context_init ( & context , PHP_OUTPUT_HANDLER_CLEAN ) ;
2010-08-27 14:09:18 +08:00
zend_stack_apply_with_argument ( & OG ( handlers ) , ZEND_STACK_APPLY_TOPDOWN , php_output_stack_apply_clean , & context ) ;
2010-03-12 18:28:59 +08:00
}
2010-05-31 18:29:43 +08:00
}
2000-11-03 00:46:30 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_end(void)
2010-12-03 23:34:24 +08:00
* Finalizes the most recent output handler at pops it off the stack if the handler is removable */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_end ( void )
2010-05-31 18:29:43 +08:00
{
2014-12-14 06:06:14 +08:00
if ( php_output_stack_pop ( PHP_OUTPUT_POP_TRY ) ) {
2010-05-31 18:29:43 +08:00
return SUCCESS ;
2001-03-07 03:38:33 +08:00
}
2010-05-31 18:29:43 +08:00
return FAILURE ;
}
/* }}} */
2000-11-03 00:46:30 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_end_all(void)
2010-12-03 23:34:24 +08:00
* Finalizes all output handlers and ends output buffering without regard whether a handler is removable */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_end_all ( void )
2010-05-31 18:29:43 +08:00
{
2014-12-14 06:06:14 +08:00
while ( OG ( active ) & & php_output_stack_pop ( PHP_OUTPUT_POP_FORCE ) ) ;
2010-05-31 18:29:43 +08:00
}
/* }}} */
2000-11-03 00:46:30 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_discard(void)
2010-12-03 23:34:24 +08:00
* Discards the most recent output handlers buffer and pops it off the stack if the handler is removable */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_discard ( void )
2010-05-31 18:29:43 +08:00
{
2014-12-14 06:06:14 +08:00
if ( php_output_stack_pop ( PHP_OUTPUT_POP_DISCARD | PHP_OUTPUT_POP_TRY ) ) {
2010-05-31 18:29:43 +08:00
return SUCCESS ;
2010-03-12 18:28:59 +08:00
}
2010-05-31 18:29:43 +08:00
return FAILURE ;
}
/* }}} */
2010-03-11 18:24:29 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_discard_all(void)
2010-12-03 23:34:24 +08:00
* Discard all output handlers and buffers without regard whether a handler is removable */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_discard_all ( void )
2010-05-31 18:29:43 +08:00
{
while ( OG ( active ) ) {
2014-12-14 06:06:14 +08:00
php_output_stack_pop ( PHP_OUTPUT_POP_DISCARD | PHP_OUTPUT_POP_FORCE ) ;
2010-03-12 18:28:59 +08:00
}
2010-05-31 18:29:43 +08:00
}
/* }}} */
2000-11-03 00:46:30 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ int php_output_get_level(void)
2010-12-03 23:34:24 +08:00
* Get output buffering level , ie . how many output handlers the stack contains */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_get_level ( void )
2010-05-31 18:29:43 +08:00
{
2010-08-27 14:09:18 +08:00
return OG ( active ) ? zend_stack_count ( & OG ( handlers ) ) : 0 ;
2010-05-31 18:29:43 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_get_contents(zval *z)
2010-12-03 23:34:24 +08:00
* Get the contents of the active output handlers buffer */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_get_contents ( zval * p )
2010-05-31 18:29:43 +08:00
{
if ( OG ( active ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( p , OG ( active ) - > buffer . data , OG ( active ) - > buffer . used ) ;
2010-05-31 18:29:43 +08:00
return SUCCESS ;
} else {
ZVAL_NULL ( p ) ;
return FAILURE ;
2001-08-31 23:56:48 +08:00
}
2010-05-31 18:29:43 +08:00
}
2001-08-31 23:56:48 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_get_length(zval *z)
2010-12-03 23:34:24 +08:00
* Get the length of the active output handlers buffer */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_get_length ( zval * p )
2010-05-31 18:29:43 +08:00
{
if ( OG ( active ) ) {
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( p , OG ( active ) - > buffer . used ) ;
2010-05-31 18:29:43 +08:00
return SUCCESS ;
} else {
ZVAL_NULL ( p ) ;
return FAILURE ;
1999-10-28 02:30:41 +08:00
}
2010-05-31 18:29:43 +08:00
}
/* }}} */
2000-11-03 00:46:30 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ php_output_handler* php_output_get_active_handler(void)
2011-12-30 17:20:07 +08:00
* Get active output handler */
2014-12-14 06:06:14 +08:00
PHPAPI php_output_handler * php_output_get_active_handler ( void )
2011-12-30 17:20:07 +08:00
{
return OG ( active ) ;
}
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_handler_start_default(void)
2010-12-03 23:34:24 +08:00
* Start a " default output handler " */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_start_default ( void )
2010-05-31 18:29:43 +08:00
{
php_output_handler * handler ;
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
handler = php_output_handler_create_internal ( ZEND_STRL ( php_output_default_handler_name ) , php_output_handler_default_func , 0 , PHP_OUTPUT_HANDLER_STDFLAGS ) ;
if ( SUCCESS = = php_output_handler_start ( handler ) ) {
2010-05-31 18:29:43 +08:00
return SUCCESS ;
2002-05-04 18:55:08 +08:00
}
2014-12-14 06:06:14 +08:00
php_output_handler_free ( & handler ) ;
2010-05-31 18:29:43 +08:00
return FAILURE ;
}
/* }}} */
2010-03-11 18:24:29 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_handler_start_devnull(void)
2010-12-03 23:34:24 +08:00
* Start a " null output handler " */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_start_devnull ( void )
2010-05-31 18:29:43 +08:00
{
php_output_handler * handler ;
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
handler = php_output_handler_create_internal ( ZEND_STRL ( php_output_devnull_handler_name ) , php_output_handler_devnull_func , PHP_OUTPUT_HANDLER_DEFAULT_SIZE , 0 ) ;
if ( SUCCESS = = php_output_handler_start ( handler ) ) {
2010-05-31 18:29:43 +08:00
return SUCCESS ;
2010-03-12 18:28:59 +08:00
}
2014-12-14 06:06:14 +08:00
php_output_handler_free ( & handler ) ;
2010-05-31 18:29:43 +08:00
return FAILURE ;
}
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_start_user(zval *handler, size_t chunk_size, int flags)
2010-12-03 23:34:24 +08:00
* Start a user level output handler */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_start_user ( zval * output_handler , size_t chunk_size , int flags )
2010-05-31 18:29:43 +08:00
{
php_output_handler * handler ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( output_handler ) {
2014-12-14 06:06:14 +08:00
handler = php_output_handler_create_user ( output_handler , chunk_size , flags ) ;
2001-03-04 09:09:36 +08:00
} else {
2014-12-14 06:06:14 +08:00
handler = php_output_handler_create_internal ( ZEND_STRL ( php_output_default_handler_name ) , php_output_handler_default_func , chunk_size , flags ) ;
2001-03-07 03:38:33 +08:00
}
2014-12-14 06:06:14 +08:00
if ( SUCCESS = = php_output_handler_start ( handler ) ) {
2010-05-31 18:29:43 +08:00
return SUCCESS ;
2000-07-29 22:46:09 +08:00
}
2014-12-14 06:06:14 +08:00
php_output_handler_free ( & handler ) ;
2010-05-31 18:29:43 +08:00
return FAILURE ;
2000-07-29 22:46:09 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
2000-07-29 22:46:09 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_start_internal(zval *name, php_output_handler_func_t handler, size_t chunk_size, int flags)
2010-12-03 23:34:24 +08:00
* Start an internal output handler that does not have to maintain a non - global state */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_start_internal ( const char * name , size_t name_len , php_output_handler_func_t output_handler , size_t chunk_size , int flags )
2000-01-14 01:37:25 +08:00
{
2010-05-31 18:29:43 +08:00
php_output_handler * handler ;
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
handler = php_output_handler_create_internal ( name , name_len , php_output_handler_compat_func , chunk_size , flags ) ;
php_output_handler_set_context ( handler , output_handler , NULL ) ;
if ( SUCCESS = = php_output_handler_start ( handler ) ) {
2010-05-31 18:29:43 +08:00
return SUCCESS ;
2010-03-11 18:24:29 +08:00
}
2014-12-14 06:06:14 +08:00
php_output_handler_free ( & handler ) ;
2010-05-31 18:29:43 +08:00
return FAILURE ;
2000-01-14 01:37:25 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
2000-01-14 01:37:25 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ php_output_handler *php_output_handler_create_user(zval *handler, size_t chunk_size, int flags)
2010-12-03 23:34:24 +08:00
* Create a user level output handler */
2014-12-14 06:06:14 +08:00
PHPAPI php_output_handler * php_output_handler_create_user ( zval * output_handler , size_t chunk_size , int flags )
2000-01-14 01:37:25 +08:00
{
2014-02-25 20:03:34 +08:00
zend_string * handler_name = NULL ;
char * error = NULL ;
2010-05-31 18:29:43 +08:00
php_output_handler * handler = NULL ;
2014-02-10 14:04:30 +08:00
php_output_handler_alias_ctor_t alias = NULL ;
2010-05-31 18:29:43 +08:00
php_output_handler_user_func_t * user = NULL ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
switch ( Z_TYPE_P ( output_handler ) ) {
case IS_NULL :
2014-12-14 06:06:14 +08:00
handler = php_output_handler_create_internal ( ZEND_STRL ( php_output_default_handler_name ) , php_output_handler_default_func , chunk_size , flags ) ;
2010-05-31 18:29:43 +08:00
break ;
case IS_STRING :
2014-12-14 06:06:14 +08:00
if ( Z_STRLEN_P ( output_handler ) & & ( alias = php_output_handler_alias ( Z_STRVAL_P ( output_handler ) , Z_STRLEN_P ( output_handler ) ) ) ) {
handler = alias ( Z_STRVAL_P ( output_handler ) , Z_STRLEN_P ( output_handler ) , chunk_size , flags ) ;
2010-05-31 18:29:43 +08:00
break ;
}
default :
user = ecalloc ( 1 , sizeof ( php_output_handler_user_func_t ) ) ;
2014-12-14 06:06:14 +08:00
if ( SUCCESS = = zend_fcall_info_init ( output_handler , 0 , & user - > fci , & user - > fcc , & handler_name , & error ) ) {
handler = php_output_handler_init ( handler_name , chunk_size , ( flags & ~ 0xf ) | PHP_OUTPUT_HANDLER_USER ) ;
2014-03-07 16:49:01 +08:00
ZVAL_COPY ( & user - > zoh , output_handler ) ;
2010-05-31 18:29:43 +08:00
handler - > func . user = user ;
} else {
efree ( user ) ;
2010-06-09 19:04:03 +08:00
}
if ( error ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( " ref.outcontrol " , E_WARNING , " %s " , error ) ;
2010-06-09 19:04:03 +08:00
efree ( error ) ;
2010-05-31 18:29:43 +08:00
}
if ( handler_name ) {
2018-05-28 21:27:12 +08:00
zend_string_release_ex ( handler_name , 0 ) ;
2010-05-31 18:29:43 +08:00
}
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return handler ;
2000-01-14 01:37:25 +08:00
}
2010-03-12 18:28:59 +08:00
/* }}} */
2000-01-14 01:37:25 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ php_output_handler *php_output_handler_create_internal(zval *name, php_output_handler_context_func_t handler, size_t chunk_size, int flags)
2010-12-03 23:34:24 +08:00
* Create an internal output handler that can maintain a non - global state */
2014-12-14 06:06:14 +08:00
PHPAPI php_output_handler * php_output_handler_create_internal ( const char * name , size_t name_len , php_output_handler_context_func_t output_handler , size_t chunk_size , int flags )
2001-03-06 23:54:49 +08:00
{
2010-05-31 18:29:43 +08:00
php_output_handler * handler ;
2017-06-21 16:25:05 +08:00
zend_string * str = zend_string_init ( name , name_len , 0 ) ;
2010-05-31 18:29:43 +08:00
2014-12-14 06:06:14 +08:00
handler = php_output_handler_init ( str , chunk_size , ( flags & ~ 0xf ) | PHP_OUTPUT_HANDLER_INTERNAL ) ;
2010-05-31 18:29:43 +08:00
handler - > func . internal = output_handler ;
2018-05-28 21:27:12 +08:00
zend_string_release_ex ( str , 0 ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return handler ;
2010-03-11 18:24:29 +08:00
}
/* }}} */
2001-03-06 23:54:49 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_handler_set_context(php_output_handler *handler, void *opaq, void (*dtor)(void*))
2010-12-03 23:34:24 +08:00
* Set the context / state of an output handler . Calls the dtor of the previous context if there is one */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_handler_set_context ( php_output_handler * handler , void * opaq , void ( * dtor ) ( void * ) )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
if ( handler - > dtor & & handler - > opaq ) {
2014-12-14 06:06:14 +08:00
handler - > dtor ( handler - > opaq ) ;
2002-10-07 19:21:06 +08:00
}
2010-05-31 18:29:43 +08:00
handler - > dtor = dtor ;
handler - > opaq = opaq ;
}
/* }}} */
2010-03-12 18:28:59 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_handler_start(php_output_handler *handler)
2010-12-03 23:34:24 +08:00
* Starts the set up output handler and pushes it on top of the stack . Checks for any conflicts regarding the output handler to start */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_handler_start ( php_output_handler * handler )
2010-05-31 18:29:43 +08:00
{
HashTable * rconflicts ;
2014-02-10 14:04:30 +08:00
php_output_handler_conflict_check_t conflict ;
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( php_output_lock_error ( PHP_OUTPUT_HANDLER_START ) | | ! handler ) {
2010-05-31 18:29:43 +08:00
return FAILURE ;
}
2014-08-13 20:55:21 +08:00
if ( NULL ! = ( conflict = zend_hash_find_ptr ( & php_output_handler_conflicts , handler - > name ) ) ) {
2015-06-30 18:59:27 +08:00
if ( SUCCESS ! = conflict ( ZSTR_VAL ( handler - > name ) , ZSTR_LEN ( handler - > name ) ) ) {
2010-05-31 18:29:43 +08:00
return FAILURE ;
}
}
2014-08-13 20:55:21 +08:00
if ( NULL ! = ( rconflicts = zend_hash_find_ptr ( & php_output_handler_reverse_conflicts , handler - > name ) ) ) {
2015-02-10 20:43:12 +08:00
ZEND_HASH_FOREACH_PTR ( rconflicts , conflict ) {
2015-06-30 18:59:27 +08:00
if ( SUCCESS ! = conflict ( ZSTR_VAL ( handler - > name ) , ZSTR_LEN ( handler - > name ) ) ) {
2010-05-31 18:29:43 +08:00
return FAILURE ;
}
2015-02-10 20:43:12 +08:00
} ZEND_HASH_FOREACH_END ( ) ;
2010-03-11 18:24:29 +08:00
}
2014-05-01 02:28:02 +08:00
/* zend_stack_push returns stack level */
handler - > level = zend_stack_push ( & OG ( handlers ) , & handler ) ;
2010-05-31 18:29:43 +08:00
OG ( active ) = handler ;
return SUCCESS ;
2001-03-06 23:54:49 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
2001-03-06 23:54:49 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ int php_output_handler_started(zval *name)
2010-12-03 23:34:24 +08:00
* Check whether a certain output handler is in use */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_handler_started ( const char * name , size_t name_len )
1999-10-28 02:30:41 +08:00
{
2014-05-01 02:28:02 +08:00
php_output_handler * * handlers ;
2014-12-14 06:06:14 +08:00
int i , count = php_output_get_level ( ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( count ) {
2014-05-01 02:28:02 +08:00
handlers = ( php_output_handler * * ) zend_stack_base ( & OG ( handlers ) ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
for ( i = 0 ; i < count ; + + i ) {
2015-06-30 18:59:27 +08:00
if ( name_len = = ZSTR_LEN ( handlers [ i ] - > name ) & & ! memcmp ( ZSTR_VAL ( handlers [ i ] - > name ) , name , name_len ) ) {
2010-05-31 18:29:43 +08:00
return 1 ;
}
2000-07-29 22:46:09 +08:00
}
1999-10-28 02:30:41 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return 0 ;
1999-10-28 02:30:41 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ int php_output_handler_conflict(zval *handler_new, zval *handler_old)
2010-12-03 23:34:24 +08:00
* Check whether a certain handler is in use and issue a warning that the new handler would conflict with the already used one */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_handler_conflict ( const char * handler_new , size_t handler_new_len , const char * handler_set , size_t handler_set_len )
1999-10-28 02:30:41 +08:00
{
2014-12-14 06:06:14 +08:00
if ( php_output_handler_started ( handler_set , handler_set_len ) ) {
2010-05-31 18:29:43 +08:00
if ( handler_new_len ! = handler_set_len | | memcmp ( handler_new , handler_set , handler_set_len ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( " ref.outcontrol " , E_WARNING , " output handler '%s' conflicts with '%s' " , handler_new , handler_set ) ;
2010-05-31 18:29:43 +08:00
} else {
2014-12-14 06:06:14 +08:00
php_error_docref ( " ref.outcontrol " , E_WARNING , " output handler '%s' cannot be used twice " , handler_new ) ;
2010-05-31 18:29:43 +08:00
}
2002-08-10 06:29:58 +08:00
return 1 ;
}
return 0 ;
}
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_handler_conflict_register(zval *name, php_output_handler_conflict_check_t check_func)
2010-12-03 23:34:24 +08:00
* Register a conflict checking function on MINIT */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_handler_conflict_register ( const char * name , size_t name_len , php_output_handler_conflict_check_t check_func )
2002-08-10 06:29:58 +08:00
{
2017-11-02 19:11:56 +08:00
zend_string * str ;
2010-05-31 18:29:43 +08:00
if ( ! EG ( current_module ) ) {
zend_error ( E_ERROR , " Cannot register an output handler conflict outside of MINIT " ) ;
return FAILURE ;
}
2017-11-02 19:11:56 +08:00
str = zend_string_init_interned ( name , name_len , 1 ) ;
2018-06-01 16:58:57 +08:00
zend_hash_update_ptr ( & php_output_handler_conflicts , str , check_func ) ;
2018-05-28 21:27:12 +08:00
zend_string_release_ex ( str , 1 ) ;
2018-06-01 16:58:57 +08:00
return SUCCESS ;
2010-05-31 18:29:43 +08:00
}
/* }}} */
2010-03-11 18:24:29 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_handler_reverse_conflict_register(zval *name, php_output_handler_conflict_check_t check_func)
2010-12-03 23:34:24 +08:00
* Register a reverse conflict checking function on MINIT */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_handler_reverse_conflict_register ( const char * name , size_t name_len , php_output_handler_conflict_check_t check_func )
2010-05-31 18:29:43 +08:00
{
HashTable rev , * rev_ptr = NULL ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( ! EG ( current_module ) ) {
zend_error ( E_ERROR , " Cannot register a reverse output handler conflict outside of MINIT " ) ;
2010-03-11 18:24:29 +08:00
return FAILURE ;
}
2010-12-03 23:34:24 +08:00
2014-05-16 01:06:39 +08:00
if ( NULL ! = ( rev_ptr = zend_hash_str_find_ptr ( & php_output_handler_reverse_conflicts , name , name_len ) ) ) {
2014-02-10 14:04:30 +08:00
return zend_hash_next_index_insert_ptr ( rev_ptr , check_func ) ? SUCCESS : FAILURE ;
2010-05-31 18:29:43 +08:00
} else {
2017-11-02 19:11:56 +08:00
zend_string * str ;
2014-04-21 22:25:34 +08:00
zend_hash_init ( & rev , 8 , NULL , NULL , 1 ) ;
2014-05-16 01:06:39 +08:00
if ( NULL = = zend_hash_next_index_insert_ptr ( & rev , check_func ) ) {
2010-05-31 18:29:43 +08:00
zend_hash_destroy ( & rev ) ;
return FAILURE ;
2010-11-03 16:35:16 +08:00
}
2017-11-02 19:11:56 +08:00
str = zend_string_init_interned ( name , name_len , 1 ) ;
2018-06-01 16:58:57 +08:00
zend_hash_update_mem ( & php_output_handler_reverse_conflicts , str , & rev , sizeof ( HashTable ) ) ;
2018-05-28 21:27:12 +08:00
zend_string_release_ex ( str , 1 ) ;
2018-06-01 16:58:57 +08:00
return SUCCESS ;
1999-10-28 02:30:41 +08:00
}
2002-08-10 06:29:58 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ php_output_handler_alias_ctor_t php_output_handler_alias(zval *name)
2010-12-03 23:34:24 +08:00
* Get an internal output handler for a user handler if it exists */
2014-12-14 06:06:14 +08:00
PHPAPI php_output_handler_alias_ctor_t php_output_handler_alias ( const char * name , size_t name_len )
2002-08-10 06:29:58 +08:00
{
2014-02-10 14:04:30 +08:00
return zend_hash_str_find_ptr ( & php_output_handler_aliases , name , name_len ) ;
1999-10-28 02:30:41 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ SUCCESS|FAILURE php_output_handler_alias_register(zval *name, php_output_handler_alias_ctor_t func)
2010-12-03 23:34:24 +08:00
* Registers an internal output handler as alias for a user handler */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_handler_alias_register ( const char * name , size_t name_len , php_output_handler_alias_ctor_t func )
2002-08-05 11:09:42 +08:00
{
2017-11-02 19:11:56 +08:00
zend_string * str ;
2010-05-31 18:29:43 +08:00
if ( ! EG ( current_module ) ) {
zend_error ( E_ERROR , " Cannot register an output handler alias outside of MINIT " ) ;
return FAILURE ;
2010-03-11 18:24:29 +08:00
}
2017-11-02 19:11:56 +08:00
str = zend_string_init_interned ( name , name_len , 1 ) ;
2018-06-01 16:58:57 +08:00
zend_hash_update_ptr ( & php_output_handler_aliases , str , func ) ;
2018-05-28 21:27:12 +08:00
zend_string_release_ex ( str , 1 ) ;
2018-06-01 16:58:57 +08:00
return SUCCESS ;
2002-08-05 11:09:42 +08:00
}
/* }}} */
2016-02-18 14:44:05 +08:00
/* {{{ SUCCESS|FAILURE php_output_handler_hook(php_output_handler_hook_t type, void *arg)
2010-12-03 23:34:24 +08:00
* Output handler hook for output handler functions to check / modify the current handlers abilities */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_handler_hook ( php_output_handler_hook_t type , void * arg )
2002-08-05 11:09:42 +08:00
{
2010-05-31 18:29:43 +08:00
if ( OG ( running ) ) {
switch ( type ) {
case PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ :
* ( void * * * ) arg = & OG ( running ) - > opaq ;
return SUCCESS ;
case PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS :
* ( int * ) arg = OG ( running ) - > flags ;
return SUCCESS ;
case PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL :
* ( int * ) arg = OG ( running ) - > level ;
2011-08-10 19:01:09 +08:00
return SUCCESS ;
2010-05-31 18:29:43 +08:00
case PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE :
OG ( running ) - > flags & = ~ ( PHP_OUTPUT_HANDLER_REMOVABLE | PHP_OUTPUT_HANDLER_CLEANABLE ) ;
return SUCCESS ;
case PHP_OUTPUT_HANDLER_HOOK_DISABLE :
OG ( running ) - > flags | = PHP_OUTPUT_HANDLER_DISABLED ;
return SUCCESS ;
default :
2010-12-03 23:34:24 +08:00
break ;
2010-05-31 18:29:43 +08:00
}
}
return FAILURE ;
2002-08-05 11:09:42 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
/* {{{ void php_output_handler_dtor(php_output_handler *handler)
2010-12-03 23:34:24 +08:00
* Destroy an output handler */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_handler_dtor ( php_output_handler * handler )
2002-08-06 02:54:53 +08:00
{
2014-08-13 20:55:21 +08:00
if ( handler - > name ) {
2018-05-28 21:27:12 +08:00
zend_string_release_ex ( handler - > name , 0 ) ;
2014-08-13 20:55:21 +08:00
}
if ( handler - > buffer . data ) {
efree ( handler - > buffer . data ) ;
}
2010-05-31 18:29:43 +08:00
if ( handler - > flags & PHP_OUTPUT_HANDLER_USER ) {
2014-03-07 16:49:01 +08:00
zval_ptr_dtor ( & handler - > func . user - > zoh ) ;
2010-05-31 18:29:43 +08:00
efree ( handler - > func . user ) ;
2002-08-06 02:54:53 +08:00
}
2010-05-31 18:29:43 +08:00
if ( handler - > dtor & & handler - > opaq ) {
2014-12-14 06:06:14 +08:00
handler - > dtor ( handler - > opaq ) ;
2002-08-06 02:54:53 +08:00
}
2010-05-31 18:29:43 +08:00
memset ( handler , 0 , sizeof ( * handler ) ) ;
2002-08-06 02:54:53 +08:00
}
/* }}} */
2016-02-18 14:44:05 +08:00
/* {{{ void php_output_handler_free(php_output_handler **handler)
2010-12-03 23:34:24 +08:00
* Destroy and free an output handler */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_handler_free ( php_output_handler * * h )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
if ( * h ) {
2014-12-14 06:06:14 +08:00
php_output_handler_dtor ( * h ) ;
2010-05-31 18:29:43 +08:00
efree ( * h ) ;
* h = NULL ;
2010-03-11 18:24:29 +08:00
}
}
/* }}} */
2000-11-24 02:43:18 +08:00
2014-12-14 06:06:14 +08:00
/* void php_output_set_implicit_flush(int enabled)
2010-12-03 23:34:24 +08:00
* Enable or disable implicit flush */
2014-12-14 06:06:14 +08:00
PHPAPI void php_output_set_implicit_flush ( int flush )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
if ( flush ) {
OG ( flags ) | = PHP_OUTPUT_IMPLICITFLUSH ;
} else {
OG ( flags ) & = ~ PHP_OUTPUT_IMPLICITFLUSH ;
2000-11-24 02:43:18 +08:00
}
1999-10-28 02:30:41 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ char *php_output_get_start_filename(void)
2010-12-03 23:34:24 +08:00
* Get the file name where output has started */
2014-12-14 06:06:14 +08:00
PHPAPI const char * php_output_get_start_filename ( void )
1999-10-28 02:30:41 +08:00
{
2010-05-31 18:29:43 +08:00
return OG ( output_start_filename ) ;
}
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ int php_output_get_start_lineno(void)
2010-12-03 23:34:24 +08:00
* Get the line number where output has started */
2014-12-14 06:06:14 +08:00
PHPAPI int php_output_get_start_lineno ( void )
2010-05-31 18:29:43 +08:00
{
return OG ( output_start_lineno ) ;
}
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ static int php_output_lock_error(int op)
2010-12-03 23:34:24 +08:00
* Checks whether an unallowed operation is attempted from within the output handler and issues a fatal error */
2014-12-14 06:06:14 +08:00
static inline int php_output_lock_error ( int op )
2010-05-31 18:29:43 +08:00
{
/* if there's no ob active, ob has been stopped */
if ( op & & OG ( active ) & & OG ( running ) ) {
/* fatal error */
2014-12-14 06:06:14 +08:00
php_output_deactivate ( ) ;
2015-11-25 23:57:01 +08:00
php_error_docref ( " ref.outcontrol " , E_ERROR , " Cannot use output buffering in output buffering display handlers " ) ;
2010-05-31 18:29:43 +08:00
return 1 ;
}
return 0 ;
}
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ static php_output_context *php_output_context_init(php_output_context *context, int op)
2010-12-03 23:34:24 +08:00
* Initialize a new output context */
2014-12-14 06:06:14 +08:00
static inline php_output_context * php_output_context_init ( php_output_context * context , int op )
2010-05-31 18:29:43 +08:00
{
if ( ! context ) {
context = emalloc ( sizeof ( php_output_context ) ) ;
1999-10-28 02:30:41 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
memset ( context , 0 , sizeof ( php_output_context ) ) ;
context - > op = op ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return context ;
1999-10-28 02:30:41 +08:00
}
2010-03-11 18:24:29 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static void php_output_context_reset(php_output_context *context)
2010-12-03 23:34:24 +08:00
* Reset an output context */
2010-05-31 18:29:43 +08:00
static inline void php_output_context_reset ( php_output_context * context )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
int op = context - > op ;
php_output_context_dtor ( context ) ;
memset ( context , 0 , sizeof ( php_output_context ) ) ;
context - > op = op ;
}
/* }}} */
1999-10-28 02:30:41 +08:00
2010-12-03 23:34:24 +08:00
/* {{{ static void php_output_context_feed(php_output_context *context, char *, size_t, size_t)
* Feed output contexts input buffer */
2010-11-03 16:35:16 +08:00
static inline void php_output_context_feed ( php_output_context * context , char * data , size_t size , size_t used , zend_bool free )
{
if ( context - > in . free & & context - > in . data ) {
efree ( context - > in . data ) ;
}
context - > in . data = data ;
context - > in . used = used ;
context - > in . free = free ;
context - > in . size = size ;
}
/* }}} */
2010-05-31 18:29:43 +08:00
/* {{{ static void php_output_context_swap(php_output_context *context)
2010-12-03 23:34:24 +08:00
* Swap output contexts buffers */
2010-05-31 18:29:43 +08:00
static inline void php_output_context_swap ( php_output_context * context )
{
if ( context - > in . free & & context - > in . data ) {
efree ( context - > in . data ) ;
}
context - > in . data = context - > out . data ;
context - > in . used = context - > out . used ;
context - > in . free = context - > out . free ;
context - > in . size = context - > out . size ;
context - > out . data = NULL ;
context - > out . used = 0 ;
2010-11-03 16:35:16 +08:00
context - > out . free = 0 ;
2010-05-31 18:29:43 +08:00
context - > out . size = 0 ;
}
/* }}} */
1999-10-28 02:30:41 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static void php_output_context_pass(php_output_context *context)
2010-12-03 23:34:24 +08:00
* Pass input to output buffer */
2010-05-31 18:29:43 +08:00
static inline void php_output_context_pass ( php_output_context * context )
{
context - > out . data = context - > in . data ;
context - > out . used = context - > in . used ;
context - > out . size = context - > in . size ;
context - > out . free = context - > in . free ;
context - > in . data = NULL ;
context - > in . used = 0 ;
2010-11-03 16:35:16 +08:00
context - > in . free = 0 ;
2010-05-31 18:29:43 +08:00
context - > in . size = 0 ;
}
/* }}} */
2010-03-12 18:28:59 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static void php_output_context_dtor(php_output_context *context)
2010-12-03 23:34:24 +08:00
* Destroy the contents of an output context */
2010-05-31 18:29:43 +08:00
static inline void php_output_context_dtor ( php_output_context * context )
{
if ( context - > in . free & & context - > in . data ) {
efree ( context - > in . data ) ;
context - > in . data = NULL ;
}
if ( context - > out . free & & context - > out . data ) {
efree ( context - > out . data ) ;
context - > out . data = NULL ;
2010-03-11 18:24:29 +08:00
}
2000-08-25 11:10:42 +08:00
}
2010-05-31 18:29:43 +08:00
/* }}} */
2000-08-25 11:10:42 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ static php_output_handler *php_output_handler_init(zval *name, size_t chunk_size, int flags)
2010-12-03 23:34:24 +08:00
* Allocates and initializes a php_output_handler structure */
2014-12-14 06:06:14 +08:00
static inline php_output_handler * php_output_handler_init ( zend_string * name , size_t chunk_size , int flags )
2010-05-31 18:29:43 +08:00
{
php_output_handler * handler ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
handler = ecalloc ( 1 , sizeof ( php_output_handler ) ) ;
2014-08-26 01:24:55 +08:00
handler - > name = zend_string_copy ( name ) ;
2010-05-31 18:29:43 +08:00
handler - > size = chunk_size ;
handler - > flags = flags ;
handler - > buffer . size = PHP_OUTPUT_HANDLER_INITBUF_SIZE ( chunk_size ) ;
handler - > buffer . data = emalloc ( handler - > buffer . size ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return handler ;
}
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ static int php_output_handler_appen(php_output_handler *handler, const php_output_buffer *buf)
2010-12-03 23:34:24 +08:00
* Appends input to the output handlers buffer and indicates whether the buffer does not have to be processed by the output handler */
2014-12-14 06:06:14 +08:00
static inline int php_output_handler_append ( php_output_handler * handler , const php_output_buffer * buf )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
if ( buf - > used ) {
OG ( flags ) | = PHP_OUTPUT_WRITTEN ;
/* 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 - ( handler - > buffer . size - handler - > buffer . used ) ) ;
size_t grow_max = MAX ( grow_int , grow_buf ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
handler - > buffer . data = erealloc ( handler - > buffer . data , handler - > buffer . size + grow_max ) ;
handler - > buffer . size + = grow_max ;
}
memcpy ( handler - > buffer . data + handler - > buffer . used , buf - > data , buf - > used ) ;
handler - > buffer . used + = buf - > used ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
/* chunked buffering */
if ( handler - > size & & ( handler - > buffer . used > = handler - > size ) ) {
/* store away errors and/or any intermediate output */
return OG ( running ) ? 1 : 0 ;
}
2010-03-11 18:24:29 +08:00
}
2010-05-31 18:29:43 +08:00
return 1 ;
2010-03-11 18:24:29 +08:00
}
/* }}} */
1999-10-28 02:30:41 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static php_output_handler_status_t php_output_handler_op(php_output_handler *handler, php_output_context *context)
2010-12-03 23:34:24 +08:00
* Output handler operation dispatcher , applying context op to the php_output_handler handler */
2010-05-31 18:29:43 +08:00
static inline php_output_handler_status_t php_output_handler_op ( php_output_handler * handler , php_output_context * context )
1999-10-28 02:30:41 +08:00
{
2010-05-31 18:29:43 +08:00
php_output_handler_status_t status ;
int original_op = context - > op ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
# if PHP_OUTPUT_DEBUG
fprintf ( stderr , " >>> op(%d, "
" handler=%p, "
" name=%s, "
" flags=%d, "
" buffer.data=%s, "
" buffer.used=%zu, "
" buffer.size=%zu, "
" in.data=%s, "
" in.used=%zu) \n " ,
context - > op ,
handler ,
handler - > name ,
handler - > flags ,
handler - > buffer . used ? handler - > buffer . data : " " ,
handler - > buffer . used ,
handler - > buffer . size ,
context - > in . used ? context - > in . data : " " ,
context - > in . used
) ;
# endif
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( php_output_lock_error ( context - > op ) ) {
2010-05-31 18:29:43 +08:00
/* fatal error */
return PHP_OUTPUT_HANDLER_FAILURE ;
2010-03-11 18:24:29 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
/* storable? */
2014-12-14 06:06:14 +08:00
if ( php_output_handler_append ( handler , & context - > in ) & & ! context - > op ) {
2012-01-17 01:51:35 +08:00
context - > op = original_op ;
return PHP_OUTPUT_HANDLER_NO_DATA ;
2010-05-31 18:29:43 +08:00
} else {
/* need to start? */
if ( ! ( handler - > flags & PHP_OUTPUT_HANDLER_STARTED ) ) {
context - > op | = PHP_OUTPUT_HANDLER_START ;
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
OG ( running ) = handler ;
if ( handler - > flags & PHP_OUTPUT_HANDLER_USER ) {
2014-02-10 14:04:30 +08:00
zval retval , ob_data , ob_mode ;
2010-12-03 23:34:24 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( & ob_data , handler - > buffer . data , handler - > buffer . used ) ;
2014-08-26 17:23:25 +08:00
ZVAL_LONG ( & ob_mode , ( zend_long ) context - > op ) ;
2014-12-14 06:06:14 +08:00
zend_fcall_info_argn ( & handler - > func . user - > fci , 2 , & ob_data , & ob_mode ) ;
2014-12-04 20:02:30 +08:00
zval_ptr_dtor ( & ob_data ) ;
2010-12-03 23:34:24 +08:00
2014-04-30 22:32:42 +08:00
# define PHP_OUTPUT_USER_SUCCESS(retval) ((Z_TYPE(retval) != IS_UNDEF) && !(Z_TYPE(retval) == IS_FALSE))
2014-12-14 06:06:14 +08:00
if ( SUCCESS = = zend_fcall_info_call ( & handler - > func . user - > fci , & handler - > func . user - > fcc , & retval , NULL ) & & PHP_OUTPUT_USER_SUCCESS ( retval ) ) {
2010-05-31 18:29:43 +08:00
/* user handler may have returned TRUE */
status = PHP_OUTPUT_HANDLER_NO_DATA ;
2014-04-30 22:32:42 +08:00
if ( Z_TYPE ( retval ) ! = IS_FALSE & & Z_TYPE ( retval ) ! = IS_TRUE ) {
2010-05-31 18:29:43 +08:00
convert_to_string_ex ( & retval ) ;
2014-08-26 01:24:55 +08:00
if ( Z_STRLEN ( retval ) ) {
context - > out . data = estrndup ( Z_STRVAL ( retval ) , Z_STRLEN ( retval ) ) ;
context - > out . used = Z_STRLEN ( retval ) ;
2010-05-31 18:29:43 +08:00
context - > out . free = 1 ;
status = PHP_OUTPUT_HANDLER_SUCCESS ;
}
}
} else {
/* call failed, pass internal buffer along */
status = PHP_OUTPUT_HANDLER_FAILURE ;
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
zend_fcall_info_argn ( & handler - > func . user - > fci , 0 ) ;
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( & retval ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
} else {
2010-11-03 16:35:16 +08:00
php_output_context_feed ( context , handler - > buffer . data , handler - > buffer . size , handler - > buffer . used , 0 ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( SUCCESS = = handler - > func . internal ( & handler - > opaq , context ) ) {
if ( context - > out . used ) {
status = PHP_OUTPUT_HANDLER_SUCCESS ;
} else {
status = PHP_OUTPUT_HANDLER_NO_DATA ;
}
} else {
status = PHP_OUTPUT_HANDLER_FAILURE ;
}
}
handler - > flags | = PHP_OUTPUT_HANDLER_STARTED ;
OG ( running ) = NULL ;
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
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 ) ;
2012-01-17 01:51:35 +08:00
/* no break */
case PHP_OUTPUT_HANDLER_SUCCESS :
/* no more buffered data */
handler - > buffer . used = 0 ;
2012-05-15 15:33:07 +08:00
handler - > flags | = PHP_OUTPUT_HANDLER_PROCESSED ;
2010-05-31 18:29:43 +08:00
break ;
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
context - > op = original_op ;
return status ;
1999-10-28 02:30:41 +08:00
}
2010-03-11 18:24:29 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ static void php_output_op(int op, const char *str, size_t len)
2010-12-03 23:34:24 +08:00
* Output op dispatcher , passes input and output handlers output through the output handler stack until it gets written to the SAPI */
2014-12-14 06:06:14 +08:00
static inline void php_output_op ( int op , const char * str , size_t len )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
php_output_context context ;
php_output_handler * * active ;
int obh_cnt ;
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( php_output_lock_error ( op ) ) {
2010-05-31 18:29:43 +08:00
return ;
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
php_output_context_init ( & context , op ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
/*
* broken up for better performance :
* - 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
*/
2010-08-27 14:09:18 +08:00
if ( OG ( active ) & & ( obh_cnt = zend_stack_count ( & OG ( handlers ) ) ) ) {
2010-05-31 18:29:43 +08:00
context . in . data = ( char * ) str ;
context . in . used = len ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( obh_cnt > 1 ) {
2010-08-27 14:09:18 +08:00
zend_stack_apply_with_argument ( & OG ( handlers ) , ZEND_STACK_APPLY_TOPDOWN , php_output_stack_apply_op , & context ) ;
2014-05-01 02:48:02 +08:00
} else if ( ( active = zend_stack_top ( & OG ( handlers ) ) ) & & ( ! ( ( * active ) - > flags & PHP_OUTPUT_HANDLER_DISABLED ) ) ) {
2010-05-31 18:29:43 +08:00
php_output_handler_op ( * active , & context ) ;
} else {
php_output_context_pass ( & context ) ;
}
} else {
context . out . data = ( char * ) str ;
context . out . used = len ;
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( context . out . data & & context . out . used ) {
2014-12-14 06:06:14 +08:00
php_output_header ( ) ;
2012-01-31 16:51:24 +08:00
if ( ! ( OG ( flags ) & PHP_OUTPUT_DISABLED ) ) {
2010-05-31 18:29:43 +08:00
# if PHP_OUTPUT_DEBUG
2012-01-31 16:51:24 +08:00
fprintf ( stderr , " ::: sapi_write('%s', %zu) \n " , context . out . data , context . out . used ) ;
2010-05-31 18:29:43 +08:00
# endif
2014-12-14 06:06:14 +08:00
sapi_module . ub_write ( context . out . data , context . out . used ) ;
2012-01-31 16:51:24 +08:00
if ( OG ( flags ) & PHP_OUTPUT_IMPLICITFLUSH ) {
2014-12-14 06:06:14 +08:00
sapi_flush ( ) ;
2010-05-31 18:29:43 +08:00
}
2012-01-31 16:51:24 +08:00
OG ( flags ) | = PHP_OUTPUT_SENT ;
2010-05-31 18:29:43 +08:00
}
}
php_output_context_dtor ( & context ) ;
2010-03-11 18:24:29 +08:00
}
2010-05-31 18:29:43 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static int php_output_stack_apply_op(void *h, void *c)
2010-12-03 23:34:24 +08:00
* Operation callback for the stack apply function */
2010-05-31 18:29:43 +08:00
static int php_output_stack_apply_op ( void * h , void * c )
2010-03-11 18:24:29 +08:00
{
2010-05-31 18:29:43 +08:00
int was_disabled ;
php_output_handler_status_t status ;
php_output_handler * handler = * ( php_output_handler * * ) h ;
php_output_context * context = ( php_output_context * ) c ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( ( was_disabled = ( handler - > flags & PHP_OUTPUT_HANDLER_DISABLED ) ) ) {
status = PHP_OUTPUT_HANDLER_FAILURE ;
} else {
status = php_output_handler_op ( handler , context ) ;
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
/*
* handler ate all = > break
* handler returned data or failed resp . is disabled = > continue
*/
switch ( status ) {
case PHP_OUTPUT_HANDLER_NO_DATA :
return 1 ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
case PHP_OUTPUT_HANDLER_SUCCESS :
/* swap contexts buffers, unless this is the last handler in the stack */
if ( handler - > level ) {
php_output_context_swap ( context ) ;
}
return 0 ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
case PHP_OUTPUT_HANDLER_FAILURE :
default :
if ( was_disabled ) {
/* pass input along, if it's the last handler in the stack */
if ( ! handler - > level ) {
php_output_context_pass ( context ) ;
}
} else {
/* swap buffers, unless this is the last handler */
if ( handler - > level ) {
php_output_context_swap ( context ) ;
}
}
return 0 ;
}
}
/* }}} */
2010-03-12 18:28:59 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static int php_output_stack_apply_clean(void *h, void *c)
2010-12-03 23:34:24 +08:00
* Clean callback for the stack apply function */
2010-05-31 18:29:43 +08:00
static int php_output_stack_apply_clean ( void * h , void * c )
{
php_output_handler * handler = * ( php_output_handler * * ) h ;
php_output_context * context = ( php_output_context * ) c ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
handler - > buffer . used = 0 ;
php_output_handler_op ( handler , context ) ;
php_output_context_reset ( context ) ;
return 0 ;
}
/* }}} */
2010-11-03 16:35:16 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static int php_output_stack_apply_list(void *h, void *z)
2010-12-03 23:34:24 +08:00
* List callback for the stack apply function */
2010-05-31 18:29:43 +08:00
static int php_output_stack_apply_list ( void * h , void * z )
{
php_output_handler * handler = * ( php_output_handler * * ) h ;
zval * array = ( zval * ) z ;
2010-12-03 23:34:24 +08:00
2014-08-26 01:24:55 +08:00
add_next_index_str ( array , zend_string_copy ( handler - > name ) ) ;
2010-05-31 18:29:43 +08:00
return 0 ;
}
/* }}} */
2010-03-12 18:28:59 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static int php_output_stack_apply_status(void *h, void *z)
2010-12-03 23:34:24 +08:00
* Status callback for the stack apply function */
2010-05-31 18:29:43 +08:00
static int php_output_stack_apply_status ( void * h , void * z )
{
php_output_handler * handler = * ( php_output_handler * * ) h ;
2014-03-07 15:12:33 +08:00
zval arr , * array = ( zval * ) z ;
2010-12-03 23:34:24 +08:00
2014-03-07 15:12:33 +08:00
add_next_index_zval ( array , php_output_handler_status ( handler , & arr ) ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return 0 ;
}
2010-03-12 18:28:59 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static zval *php_output_handler_status(php_output_handler *handler, zval *entry)
2010-12-03 23:34:24 +08:00
* Returns an array with the status of the output handler */
2010-05-31 18:29:43 +08:00
static inline zval * php_output_handler_status ( php_output_handler * handler , zval * entry )
{
2014-02-10 14:04:30 +08:00
ZEND_ASSERT ( entry ! = NULL ) ;
2010-12-03 23:34:24 +08:00
2014-02-10 14:04:30 +08:00
array_init ( entry ) ;
2014-08-26 01:24:55 +08:00
add_assoc_str ( entry , " name " , zend_string_copy ( handler - > name ) ) ;
add_assoc_long ( entry , " type " , ( zend_long ) ( handler - > flags & 0xf ) ) ;
add_assoc_long ( entry , " flags " , ( zend_long ) handler - > flags ) ;
add_assoc_long ( entry , " level " , ( zend_long ) handler - > level ) ;
add_assoc_long ( entry , " chunk_size " , ( zend_long ) handler - > size ) ;
add_assoc_long ( entry , " buffer_size " , ( zend_long ) handler - > buffer . size ) ;
add_assoc_long ( entry , " buffer_used " , ( zend_long ) handler - > buffer . used ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return entry ;
1999-10-28 02:30:41 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2014-12-14 06:06:14 +08:00
/* {{{ static int php_output_stack_pop(int flags)
2010-12-03 23:34:24 +08:00
* Pops an output handler off the stack */
2014-12-14 06:06:14 +08:00
static inline int php_output_stack_pop ( int flags )
1999-10-28 02:30:41 +08:00
{
2010-05-31 18:29:43 +08:00
php_output_context context ;
php_output_handler * * current , * orphan = OG ( active ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( ! orphan ) {
if ( ! ( flags & PHP_OUTPUT_POP_SILENT ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to %s buffer. No buffer to %s " , ( flags & PHP_OUTPUT_POP_DISCARD ) ? " discard " : " send " , ( flags & PHP_OUTPUT_POP_DISCARD ) ? " discard " : " send " ) ;
2010-05-31 18:29:43 +08:00
}
return 0 ;
} else if ( ! ( flags & PHP_OUTPUT_POP_FORCE ) & & ! ( orphan - > flags & PHP_OUTPUT_HANDLER_REMOVABLE ) ) {
if ( ! ( flags & PHP_OUTPUT_POP_SILENT ) ) {
2015-06-30 18:59:27 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to %s buffer of %s (%d) " , ( flags & PHP_OUTPUT_POP_DISCARD ) ? " discard " : " send " , ZSTR_VAL ( orphan - > name ) , orphan - > level ) ;
2010-05-31 18:29:43 +08:00
}
return 0 ;
} else {
2014-12-14 06:06:14 +08:00
php_output_context_init ( & context , PHP_OUTPUT_HANDLER_FINAL ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
/* don't run the output handler if it's disabled */
if ( ! ( orphan - > flags & PHP_OUTPUT_HANDLER_DISABLED ) ) {
/* didn't it start yet? */
if ( ! ( orphan - > flags & PHP_OUTPUT_HANDLER_STARTED ) ) {
context . op | = PHP_OUTPUT_HANDLER_START ;
}
/* signal that we're cleaning up */
if ( flags & PHP_OUTPUT_POP_DISCARD ) {
context . op | = PHP_OUTPUT_HANDLER_CLEAN ;
}
php_output_handler_op ( orphan , & context ) ;
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
/* pop it off the stack */
2010-08-27 14:09:18 +08:00
zend_stack_del_top ( & OG ( handlers ) ) ;
2014-05-01 02:48:02 +08:00
if ( ( current = zend_stack_top ( & OG ( handlers ) ) ) ) {
2010-05-31 18:29:43 +08:00
OG ( active ) = * current ;
} else {
OG ( active ) = NULL ;
2004-10-20 23:31:06 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
/* pass output along */
if ( context . out . data & & context . out . used & & ! ( flags & PHP_OUTPUT_POP_DISCARD ) ) {
2014-12-14 06:06:14 +08:00
php_output_write ( context . out . data , context . out . used ) ;
2000-02-04 22:54:30 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
/* destroy the handler (after write!) */
2014-12-14 06:06:14 +08:00
php_output_handler_free ( & orphan ) ;
2010-05-31 18:29:43 +08:00
php_output_context_dtor ( & context ) ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return 1 ;
}
}
/* }}} */
2000-02-04 22:54:30 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static SUCCESS|FAILURE php_output_handler_compat_func(void *ctx, php_output_context *)
2010-12-03 23:34:24 +08:00
* php_output_handler_context_func_t for php_output_handler_func_t output handlers */
2010-05-31 18:29:43 +08:00
static int php_output_handler_compat_func ( void * * handler_context , php_output_context * output_context )
{
php_output_handler_func_t func = * ( php_output_handler_func_t * ) handler_context ;
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( func ) {
2012-02-15 03:31:54 +08:00
char * out_str = NULL ;
2014-10-27 20:08:21 +08:00
size_t out_len = 0 ;
2012-02-15 03:31:54 +08:00
2014-12-14 06:06:14 +08:00
func ( output_context - > in . data , output_context - > in . used , & out_str , & out_len , output_context - > op ) ;
2012-02-15 03:31:54 +08:00
if ( out_str ) {
output_context - > out . data = out_str ;
output_context - > out . used = out_len ;
output_context - > out . free = 1 ;
} else {
php_output_context_pass ( output_context ) ;
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
return SUCCESS ;
1999-10-28 02:30:41 +08:00
}
2010-05-31 18:29:43 +08:00
return FAILURE ;
}
/* }}} */
/* {{{ static SUCCESS|FAILURE php_output_handler_default_func(void *ctx, php_output_context *)
2010-12-03 23:34:24 +08:00
* Default output handler */
2010-05-31 18:29:43 +08:00
static int php_output_handler_default_func ( void * * handler_context , php_output_context * output_context )
{
2010-11-03 16:35:16 +08:00
php_output_context_pass ( output_context ) ;
2010-05-31 18:29:43 +08:00
return SUCCESS ;
}
/* }}} */
1999-10-28 02:30:41 +08:00
2010-05-31 18:29:43 +08:00
/* {{{ static SUCCESS|FAILURE php_output_handler_devnull_func(void *ctx, php_output_context *)
2010-12-03 23:34:24 +08:00
* Null output handler */
2010-05-31 18:29:43 +08:00
static int php_output_handler_devnull_func ( void * * handler_context , php_output_context * output_context )
{
return SUCCESS ;
1999-10-28 02:30:41 +08:00
}
2001-06-06 21:06:12 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
/*
2010-05-31 18:29:43 +08:00
* USERLAND ( nearly 1 : 1 of old output . c )
1999-10-28 02:30:41 +08:00
*/
2010-05-31 18:29:43 +08:00
/* {{{ proto bool ob_start([string|array user_function [, int chunk_size [, int flags]]])
2000-11-13 06:13:35 +08:00
Turn on Output Buffering ( specifying an optional output handler ) . */
1999-10-28 02:30:41 +08:00
PHP_FUNCTION ( ob_start )
{
2010-05-31 18:29:43 +08:00
zval * output_handler = NULL ;
2014-08-26 01:24:55 +08:00
zend_long chunk_size = 0 ;
zend_long flags = PHP_OUTPUT_HANDLER_STDFLAGS ;
2010-12-03 23:34:24 +08:00
2018-06-26 01:00:37 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |zll " , & output_handler , & chunk_size , & flags ) = = FAILURE ) {
2010-12-03 23:34:24 +08:00
return ;
2002-10-07 19:21:06 +08:00
}
2010-03-12 18:28:59 +08:00
2010-12-03 23:34:24 +08:00
if ( chunk_size < 0 ) {
2003-04-04 02:19:15 +08:00
chunk_size = 0 ;
2010-12-03 23:34:24 +08:00
}
2010-03-12 18:28:59 +08:00
2014-12-14 06:06:14 +08:00
if ( php_output_start_user ( output_handler , chunk_size , flags ) = = FAILURE ) {
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to create buffer " ) ;
2000-09-03 02:03:58 +08:00
RETURN_FALSE ;
}
RETURN_TRUE ;
1999-10-28 02:30:41 +08:00
}
2000-04-19 03:18:47 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2010-03-12 18:28:59 +08:00
/* {{{ proto bool ob_flush(void)
2002-10-03 15:17:14 +08:00
Flush ( send ) contents of the output buffer . The last buffer content is sent to next buffer */
2001-11-30 18:48:38 +08:00
PHP_FUNCTION ( ob_flush )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-10-07 19:21:06 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( ! OG ( active ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to flush buffer. No buffer to flush " ) ;
2002-03-01 11:05:50 +08:00
RETURN_FALSE ;
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( SUCCESS ! = php_output_flush ( ) ) {
2015-06-30 18:59:27 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to flush buffer of %s (%d) " , ZSTR_VAL ( OG ( active ) - > name ) , OG ( active ) - > level ) ;
2009-02-13 19:48:17 +08:00
RETURN_FALSE ;
}
2002-03-01 11:05:50 +08:00
RETURN_TRUE ;
2001-11-30 18:48:38 +08:00
}
/* }}} */
2010-03-12 18:28:59 +08:00
/* {{{ proto bool ob_clean(void)
2002-03-01 11:05:50 +08:00
Clean ( delete ) the current output buffer */
2001-11-30 18:48:38 +08:00
PHP_FUNCTION ( ob_clean )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-10-07 19:21:06 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( ! OG ( active ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to delete buffer. No buffer to delete " ) ;
2002-03-01 11:05:50 +08:00
RETURN_FALSE ;
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( SUCCESS ! = php_output_clean ( ) ) {
2015-06-30 18:59:27 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to delete buffer of %s (%d) " , ZSTR_VAL ( OG ( active ) - > name ) , OG ( active ) - > level ) ;
2002-03-01 11:05:50 +08:00
RETURN_FALSE ;
}
RETURN_TRUE ;
2001-11-30 18:48:38 +08:00
}
/* }}} */
2010-03-12 18:28:59 +08:00
/* {{{ proto bool ob_end_flush(void)
2002-03-01 11:05:50 +08:00
Flush ( send ) the output buffer , and delete current output buffer */
1999-10-28 02:30:41 +08:00
PHP_FUNCTION ( ob_end_flush )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-10-07 19:21:06 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( ! OG ( active ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to delete and flush buffer. No buffer to delete or flush " ) ;
2010-03-12 18:28:59 +08:00
RETURN_FALSE ;
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
RETURN_BOOL ( SUCCESS = = php_output_end ( ) ) ;
1999-10-28 02:30:41 +08:00
}
2000-04-19 03:18:47 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2010-03-12 18:28:59 +08:00
/* {{{ proto bool ob_end_clean(void)
2002-03-01 11:05:50 +08:00
Clean the output buffer , and delete current output buffer */
1999-10-28 02:30:41 +08:00
PHP_FUNCTION ( ob_end_clean )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-10-07 19:21:06 +08:00
}
2010-12-03 23:34:24 +08:00
2010-05-31 18:29:43 +08:00
if ( ! OG ( active ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to delete buffer. No buffer to delete " ) ;
2010-03-12 18:28:59 +08:00
RETURN_FALSE ;
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
RETURN_BOOL ( SUCCESS = = php_output_discard ( ) ) ;
1999-10-28 02:30:41 +08:00
}
2000-04-19 03:18:47 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2010-03-12 18:28:59 +08:00
/* {{{ proto bool ob_get_flush(void)
2002-10-03 09:36:44 +08:00
Get current buffer contents , flush ( send ) the output buffer , and delete current output buffer */
PHP_FUNCTION ( ob_get_flush )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-10-07 19:21:06 +08:00
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( php_output_get_contents ( return_value ) = = FAILURE ) {
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to delete and flush buffer. No buffer to delete or flush " ) ;
2010-03-12 18:28:59 +08:00
RETURN_FALSE ;
2002-10-03 09:36:44 +08:00
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( SUCCESS ! = php_output_end ( ) ) {
2015-06-30 18:59:27 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to delete buffer of %s (%d) " , ZSTR_VAL ( OG ( active ) - > name ) , OG ( active ) - > level ) ;
2010-03-12 18:28:59 +08:00
}
2002-10-03 09:36:44 +08:00
}
/* }}} */
2010-03-12 18:28:59 +08:00
/* {{{ proto bool ob_get_clean(void)
2002-10-03 09:36:44 +08:00
Get current buffer contents and delete current output buffer */
PHP_FUNCTION ( ob_get_clean )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2010-12-03 23:34:24 +08:00
2011-12-26 13:01:46 +08:00
if ( ! OG ( active ) ) {
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
if ( php_output_get_contents ( return_value ) = = FAILURE ) {
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to delete buffer. No buffer to delete " ) ;
2010-03-12 18:28:59 +08:00
RETURN_FALSE ;
2002-10-03 09:36:44 +08:00
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( SUCCESS ! = php_output_discard ( ) ) {
2015-06-30 18:59:27 +08:00
php_error_docref ( " ref.outcontrol " , E_NOTICE , " failed to delete buffer of %s (%d) " , ZSTR_VAL ( OG ( active ) - > name ) , OG ( active ) - > level ) ;
2010-03-12 18:28:59 +08:00
}
2002-10-03 09:36:44 +08:00
}
/* }}} */
2010-03-12 18:28:59 +08:00
/* {{{ proto string ob_get_contents(void)
2000-04-19 03:18:47 +08:00
Return the contents of the output buffer */
1999-10-28 02:30:41 +08:00
PHP_FUNCTION ( ob_get_contents )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-10-07 19:21:06 +08:00
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( php_output_get_contents ( return_value ) = = FAILURE ) {
1999-10-28 02:30:41 +08:00
RETURN_FALSE ;
}
}
2000-04-19 03:18:47 +08:00
/* }}} */
1999-10-28 02:30:41 +08:00
2010-03-12 18:28:59 +08:00
/* {{{ proto int ob_get_level(void)
2001-12-03 15:43:53 +08:00
Return the nesting level of the output buffer */
PHP_FUNCTION ( ob_get_level )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-10-07 19:21:06 +08:00
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
RETURN_LONG ( php_output_get_level ( ) ) ;
2001-12-03 15:43:53 +08:00
}
/* }}} */
2010-03-12 18:28:59 +08:00
/* {{{ proto int ob_get_length(void)
2000-08-25 11:10:42 +08:00
Return the length of the output buffer */
PHP_FUNCTION ( ob_get_length )
{
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
2002-10-07 19:21:06 +08:00
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( php_output_get_length ( return_value ) = = FAILURE ) {
2000-08-25 11:10:42 +08:00
RETURN_FALSE ;
}
}
/* }}} */
2010-05-31 18:29:43 +08:00
/* {{{ proto false|array ob_list_handlers()
2010-12-03 23:34:24 +08:00
List all output_buffers in an array */
2010-05-31 18:29:43 +08:00
PHP_FUNCTION ( ob_list_handlers )
2002-03-01 11:05:50 +08:00
{
2010-05-31 18:29:43 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2002-03-01 11:05:50 +08:00
2010-05-31 18:29:43 +08:00
array_init ( return_value ) ;
2002-03-01 17:29:32 +08:00
2010-05-31 18:29:43 +08:00
if ( ! OG ( active ) ) {
return ;
2010-03-12 18:28:59 +08:00
}
2010-12-03 23:34:24 +08:00
2010-08-27 14:09:18 +08:00
zend_stack_apply_with_argument ( & OG ( handlers ) , ZEND_STACK_APPLY_BOTTOMUP , php_output_stack_apply_list , return_value ) ;
2002-03-01 11:05:50 +08:00
}
2002-10-03 12:17:41 +08:00
/* }}} */
2002-03-01 11:05:50 +08:00
2010-03-12 18:28:59 +08:00
/* {{{ proto false|array ob_get_status([bool full_status])
2002-08-10 06:29:58 +08:00
Return the status of the active or all output buffers */
2002-03-01 11:05:50 +08:00
PHP_FUNCTION ( ob_get_status )
{
zend_bool full_status = 0 ;
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |b " , & full_status ) = = FAILURE ) {
2010-12-03 23:34:24 +08:00
return ;
2010-03-11 18:24:29 +08:00
}
2015-01-03 17:22:58 +08:00
2010-05-31 18:29:43 +08:00
if ( ! OG ( active ) ) {
2014-03-07 17:48:54 +08:00
array_init ( return_value ) ;
2011-11-18 08:16:58 +08:00
return ;
2010-05-31 18:29:43 +08:00
}
2010-12-03 23:34:24 +08:00
2002-03-01 11:05:50 +08:00
if ( full_status ) {
2014-03-07 17:48:54 +08:00
array_init ( return_value ) ;
2010-08-27 14:09:18 +08:00
zend_stack_apply_with_argument ( & OG ( handlers ) , ZEND_STACK_APPLY_BOTTOMUP , php_output_stack_apply_status , return_value ) ;
2010-05-31 18:29:43 +08:00
} else {
php_output_handler_status ( OG ( active ) , return_value ) ;
2002-03-01 11:05:50 +08:00
}
}
/* }}} */
2010-03-12 18:28:59 +08:00
/* {{{ proto void ob_implicit_flush([int flag])
2000-04-19 04:00:21 +08:00
Turn implicit flush on / off and is equivalent to calling flush ( ) after every output call */
2000-01-14 01:37:25 +08:00
PHP_FUNCTION ( ob_implicit_flush )
{
2014-08-26 01:24:55 +08:00
zend_long flag = 1 ;
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |l " , & flag ) = = FAILURE ) {
2010-12-03 23:34:24 +08:00
return ;
2010-03-12 18:28:59 +08:00
}
2010-12-03 23:34:24 +08:00
2014-12-14 06:06:14 +08:00
php_output_set_implicit_flush ( flag ) ;
2010-03-12 18:28:59 +08:00
}
/* }}} */
2002-10-03 12:17:41 +08:00
/* {{{ proto bool output_reset_rewrite_vars(void)
Reset ( clear ) URL rewriter values */
2002-05-05 02:33:13 +08:00
PHP_FUNCTION ( output_reset_rewrite_vars )
2002-05-03 16:00:41 +08:00
{
2014-12-14 06:06:14 +08:00
if ( php_url_scanner_reset_vars ( ) = = SUCCESS ) {
2002-05-03 16:00:41 +08:00
RETURN_TRUE ;
} else {
RETURN_FALSE ;
}
}
2002-10-03 12:17:41 +08:00
/* }}} */
2002-05-03 16:00:41 +08:00
2002-10-03 12:17:41 +08:00
/* {{{ proto bool output_add_rewrite_var(string name, string value)
Add URL rewriter values */
2002-05-03 16:00:41 +08:00
PHP_FUNCTION ( output_add_rewrite_var )
{
char * name , * value ;
2014-08-27 21:31:48 +08:00
size_t name_len , value_len ;
2002-05-03 16:00:41 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " ss " , & name , & name_len , & value , & value_len ) = = FAILURE ) {
2010-12-03 23:34:24 +08:00
return ;
2002-05-03 16:00:41 +08:00
}
2014-12-14 06:06:14 +08:00
if ( php_url_scanner_add_var ( name , name_len , value , value_len , 1 ) = = SUCCESS ) {
2002-05-03 16:00:41 +08:00
RETURN_TRUE ;
} else {
RETURN_FALSE ;
}
}
2002-10-03 12:17:41 +08:00
/* }}} */
2002-05-03 16:00:41 +08:00
1999-10-28 02:30:41 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2001-09-09 21:29:31 +08:00
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
1999-10-28 02:30:41 +08:00
*/