* implement new output API, fixing some bugs and implementing some feature

requests--let's see what I can dig out of the bugtracker for NEWS--
  and while crossing the road:
   * implemented new zlib API
   * fixed up ext/tidy (what was "s&" in zend_parse_parameters() supposed to do?)

Thanks to Jani and Felipe for pioneering.
This commit is contained in:
Michael Wallner 2010-05-31 10:29:43 +00:00
parent 27299b7e40
commit 11d24c1593
85 changed files with 3561 additions and 2701 deletions

426
README.NEW-OUTPUT-API Normal file
View file

@ -0,0 +1,426 @@
$Id: README.NEW-OUTPUT-API 219039 2006-08-30 07:39:09Z mike $
API adjustment to the old output control code:
Everything now resides beneath the php_output namespace,
and there's an API call for every output handler op.
Checking output control layers status:
// Using OG()
php_output_get_status(TSRMLS_C);
Starting the default output handler:
// php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
php_output_start_default(TSRMLS_C);
Starting an user handler by zval:
// php_start_ob_buffer(zhandler, chunk_size, erase TSRMLS_CC);
php_output_start_user(zhandler, chunk_size, flags TSRMLS_CC);
Starting an internal handler whithout context:
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase TSRMLS_CC);
php_output_start_internal(handler_name_zval, my_php_output_handler_func_t, chunk_size, flags TSRMLS_CC);
Starting an internal handler with context:
// not possible with old API
php_output_handler *h;
h = php_output_handler_create_internal(handler_name_zval, my_php_output_handler_context_func_t, chunk_size, flags TSRMLS_CC);
php_output_handler_set_context(h, my_context, my_context_dtor);
php_output_handler_start(h TSRMLS_CC);
Testing whether a certain output handler has already been started:
// php_ob_handler_used("output handler name" TSRMLS_CC);
php_output_handler_started(handler_name_zval TSRMLS_CC);
Flushing one output buffer:
// php_ob_end_buffer(1, 1 TSRMLS_CC);
php_output_flush(TSRMLS_C);
Flushing all output buffers:
// not possible with old API
php_output_flush_all(TSRMLS_C);
Cleaning one output buffer:
// php_ob_end_buffer(0, 1 TSRMLS_CC);
php_output_clean(TSRMLS_C);
Cleaning all output buffers:
// not possible with old API
php_output_clean_all(TSRMLS_C);
Discarding one output buffer:
// php_ob_end_buffer(0, 0 TSRMLS_CC);
php_output_discard(TSRMLS_C);
Discarding all output buffers:
// php_ob_end_buffers(0 TSRMLS_CC);
php_output_discard_all(TSRMLS_C);
Stopping (and dropping) one output buffer:
// php_ob_end_buffer(1, 0 TSRMLS_CC)
php_output_end(TSRMLS_C);
Stopping (and dropping) all output buffers:
// php_ob_end_buffers(1, 0 TSRMLS_CC);
php_output_end_all(TSRMLS_C);
Retrieving output buffers contents:
// php_ob_get_buffer(zstring TSRMLS_CC);
php_output_get_contents(zstring TSRMLS_CC);
Retrieving output buffers length:
// php_ob_get_length(zlength TSRMLS_CC);
php_output_get_length(zlength TSRMLS_CC);
Retrieving output buffering level:
// OG(nesting_level);
php_output_get_level(TSRMLS_C);
Issue a warning because of an output handler conflict:
// php_ob_init_conflict("to be started handler name", "to be tested if already started handler name" TSRMLS_CC);
php_output_handler_conflict(new_handler_name_zval, set_handler_name_zval TSRMLS_CC);
Registering a conflict checking function, which will be checked prior starting the handler:
// not possible with old API, unless hardcoding into output.c
php_output_handler_conflict_register(handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler:
// not possible with old API
php_output_handler_reverse_conflict_register(foreign_handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
Facilitating a context from within an output handler callable with ob_start():
// not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr TSRMLS_CC);
Disabling of the output handler by itself:
//not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL TSRMLS_CC);
Marking an output handler immutable by itself because of irreversibility of its operation:
// not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
Restarting the output handler because of a CLEAN operation:
// not possible with old API
if (flags & PHP_OUTPUT_HANDLER_CLEAN) { ... }
Recognizing by the output handler itself if it gets discarded:
// not possible with old API
if ((flags & PHP_OUTPUT_HANDLER_CLEAN) && (flags & PHP_OUTPUT_HANDLER_FINAL)) { ... }
Output handler hooks
The output handler can change its abilities at runtime. Eg. the gz handler can
remove the CLEANABLE and REMOVABLE bits when the first output has passed through it;
or handlers implemented in C to be used with ob_start() can contain a non-global
context:
PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ
pass a void*** pointer as second arg to receive the address of a pointer
pointer to the opaque field of the output handler context
PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS
pass a int* pointer as second arg to receive the flags set for the output handler
PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL
pass a int* pointer as second arg to receive the level of this output handler
(starts with 0)
PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE
the second arg is ignored; marks the output handler to be neither cleanable
nor removable
PHP_OUTPUT_HANDLER_HOOK_DISABLE
the second arg is ignored; marks the output handler as disabled
Open questions
Should the userland API be adjusted and unified?
Many bits of the manual (and very first implementation) do not comply
with the behaviour of the current (to be obsoleted) code, thus should
the manual or the behaviour be adjusted?
END
$Id: README.NEW-OUTPUT-API 219039 2006-08-30 07:39:09Z mike $
API adjustment to the old output control code:
Everything now resides beneath the php_output namespace,
and there's an API call for every output handler op.
Checking output control layers status:
// Using OG()
php_output_get_status(TSRMLS_C);
Starting the default output handler:
// php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
php_output_start_default(TSRMLS_C);
Starting an user handler by zval:
// php_start_ob_buffer(zhandler, chunk_size, erase TSRMLS_CC);
php_output_start_user(zhandler, chunk_size, flags TSRMLS_CC);
Starting an internal handler whithout context:
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase TSRMLS_CC);
php_output_start_internal(handler_name_zval, my_php_output_handler_func_t, chunk_size, flags TSRMLS_CC);
Starting an internal handler with context:
// not possible with old API
php_output_handler *h;
h = php_output_handler_create_internal(handler_name_zval, my_php_output_handler_context_func_t, chunk_size, flags TSRMLS_CC);
php_output_handler_set_context(h, my_context, my_context_dtor);
php_output_handler_start(h TSRMLS_CC);
Testing whether a certain output handler has already been started:
// php_ob_handler_used("output handler name" TSRMLS_CC);
php_output_handler_started(handler_name_zval TSRMLS_CC);
Flushing one output buffer:
// php_ob_end_buffer(1, 1 TSRMLS_CC);
php_output_flush(TSRMLS_C);
Flushing all output buffers:
// not possible with old API
php_output_flush_all(TSRMLS_C);
Cleaning one output buffer:
// php_ob_end_buffer(0, 1 TSRMLS_CC);
php_output_clean(TSRMLS_C);
Cleaning all output buffers:
// not possible with old API
php_output_clean_all(TSRMLS_C);
Discarding one output buffer:
// php_ob_end_buffer(0, 0 TSRMLS_CC);
php_output_discard(TSRMLS_C);
Discarding all output buffers:
// php_ob_end_buffers(0 TSRMLS_CC);
php_output_discard_all(TSRMLS_C);
Stopping (and dropping) one output buffer:
// php_ob_end_buffer(1, 0 TSRMLS_CC)
php_output_end(TSRMLS_C);
Stopping (and dropping) all output buffers:
// php_ob_end_buffers(1, 0 TSRMLS_CC);
php_output_end_all(TSRMLS_C);
Retrieving output buffers contents:
// php_ob_get_buffer(zstring TSRMLS_CC);
php_output_get_contents(zstring TSRMLS_CC);
Retrieving output buffers length:
// php_ob_get_length(zlength TSRMLS_CC);
php_output_get_length(zlength TSRMLS_CC);
Retrieving output buffering level:
// OG(nesting_level);
php_output_get_level(TSRMLS_C);
Issue a warning because of an output handler conflict:
// php_ob_init_conflict("to be started handler name", "to be tested if already started handler name" TSRMLS_CC);
php_output_handler_conflict(new_handler_name_zval, set_handler_name_zval TSRMLS_CC);
Registering a conflict checking function, which will be checked prior starting the handler:
// not possible with old API, unless hardcoding into output.c
php_output_handler_conflict_register(handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler:
// not possible with old API
php_output_handler_reverse_conflict_register(foreign_handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
Facilitating a context from within an output handler callable with ob_start():
// not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr TSRMLS_CC);
Disabling of the output handler by itself:
//not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL TSRMLS_CC);
Marking an output handler immutable by itself because of irreversibility of its operation:
// not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
Restarting the output handler because of a CLEAN operation:
// not possible with old API
if (flags & PHP_OUTPUT_HANDLER_CLEAN) { ... }
Recognizing by the output handler itself if it gets discarded:
// not possible with old API
if ((flags & PHP_OUTPUT_HANDLER_CLEAN) && (flags & PHP_OUTPUT_HANDLER_FINAL)) { ... }
Output handler hooks
The output handler can change its abilities at runtime. Eg. the gz handler can
remove the CLEANABLE and REMOVABLE bits when the first output has passed through it;
or handlers implemented in C to be used with ob_start() can contain a non-global
context:
PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ
pass a void*** pointer as second arg to receive the address of a pointer
pointer to the opaque field of the output handler context
PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS
pass a int* pointer as second arg to receive the flags set for the output handler
PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL
pass a int* pointer as second arg to receive the level of this output handler
(starts with 0)
PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE
the second arg is ignored; marks the output handler to be neither cleanable
nor removable
PHP_OUTPUT_HANDLER_HOOK_DISABLE
the second arg is ignored; marks the output handler as disabled
Open questions
Should the userland API be adjusted and unified?
Many bits of the manual (and very first implementation) do not comply
with the behaviour of the current (to be obsoleted) code, thus should
the manual or the behaviour be adjusted?
END
$Id: README.NEW-OUTPUT-API 219039 2006-08-30 07:39:09Z mike $
API adjustment to the old output control code:
Everything now resides beneath the php_output namespace,
and there's an API call for every output handler op.
Checking output control layers status:
// Using OG()
php_output_get_status(TSRMLS_C);
Starting the default output handler:
// php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
php_output_start_default(TSRMLS_C);
Starting an user handler by zval:
// php_start_ob_buffer(zhandler, chunk_size, erase TSRMLS_CC);
php_output_start_user(zhandler, chunk_size, flags TSRMLS_CC);
Starting an internal handler whithout context:
// php_ob_set_internal_handler(my_php_output_handler_func_t, buffer_size, "output handler name", erase TSRMLS_CC);
php_output_start_internal(handler_name_zval, my_php_output_handler_func_t, chunk_size, flags TSRMLS_CC);
Starting an internal handler with context:
// not possible with old API
php_output_handler *h;
h = php_output_handler_create_internal(handler_name_zval, my_php_output_handler_context_func_t, chunk_size, flags TSRMLS_CC);
php_output_handler_set_context(h, my_context, my_context_dtor);
php_output_handler_start(h TSRMLS_CC);
Testing whether a certain output handler has already been started:
// php_ob_handler_used("output handler name" TSRMLS_CC);
php_output_handler_started(handler_name_zval TSRMLS_CC);
Flushing one output buffer:
// php_ob_end_buffer(1, 1 TSRMLS_CC);
php_output_flush(TSRMLS_C);
Flushing all output buffers:
// not possible with old API
php_output_flush_all(TSRMLS_C);
Cleaning one output buffer:
// php_ob_end_buffer(0, 1 TSRMLS_CC);
php_output_clean(TSRMLS_C);
Cleaning all output buffers:
// not possible with old API
php_output_clean_all(TSRMLS_C);
Discarding one output buffer:
// php_ob_end_buffer(0, 0 TSRMLS_CC);
php_output_discard(TSRMLS_C);
Discarding all output buffers:
// php_ob_end_buffers(0 TSRMLS_CC);
php_output_discard_all(TSRMLS_C);
Stopping (and dropping) one output buffer:
// php_ob_end_buffer(1, 0 TSRMLS_CC)
php_output_end(TSRMLS_C);
Stopping (and dropping) all output buffers:
// php_ob_end_buffers(1, 0 TSRMLS_CC);
php_output_end_all(TSRMLS_C);
Retrieving output buffers contents:
// php_ob_get_buffer(zstring TSRMLS_CC);
php_output_get_contents(zstring TSRMLS_CC);
Retrieving output buffers length:
// php_ob_get_length(zlength TSRMLS_CC);
php_output_get_length(zlength TSRMLS_CC);
Retrieving output buffering level:
// OG(nesting_level);
php_output_get_level(TSRMLS_C);
Issue a warning because of an output handler conflict:
// php_ob_init_conflict("to be started handler name", "to be tested if already started handler name" TSRMLS_CC);
php_output_handler_conflict(new_handler_name_zval, set_handler_name_zval TSRMLS_CC);
Registering a conflict checking function, which will be checked prior starting the handler:
// not possible with old API, unless hardcoding into output.c
php_output_handler_conflict_register(handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
Registering a reverse conflict checking function, which will be checked prior starting the specified foreign handler:
// not possible with old API
php_output_handler_reverse_conflict_register(foreign_handler_name_zval, my_php_output_handler_conflict_check_t TSRMLS_CC);
Facilitating a context from within an output handler callable with ob_start():
// not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ, (void *) &custom_ctx_ptr_ptr TSRMLS_CC);
Disabling of the output handler by itself:
//not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_DISABLE, NULL TSRMLS_CC);
Marking an output handler immutable by itself because of irreversibility of its operation:
// not possible with old API
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
Restarting the output handler because of a CLEAN operation:
// not possible with old API
if (flags & PHP_OUTPUT_HANDLER_CLEAN) { ... }
Recognizing by the output handler itself if it gets discarded:
// not possible with old API
if ((flags & PHP_OUTPUT_HANDLER_CLEAN) && (flags & PHP_OUTPUT_HANDLER_FINAL)) { ... }
Output handler hooks
The output handler can change its abilities at runtime. Eg. the gz handler can
remove the CLEANABLE and REMOVABLE bits when the first output has passed through it;
or handlers implemented in C to be used with ob_start() can contain a non-global
context:
PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ
pass a void*** pointer as second arg to receive the address of a pointer
pointer to the opaque field of the output handler context
PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS
pass a int* pointer as second arg to receive the flags set for the output handler
PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL
pass a int* pointer as second arg to receive the level of this output handler
(starts with 0)
PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE
the second arg is ignored; marks the output handler to be neither cleanable
nor removable
PHP_OUTPUT_HANDLER_HOOK_DISABLE
the second arg is ignored; marks the output handler as disabled
Open questions
Should the userland API be adjusted and unified?
Many bits of the manual (and very first implementation) do not comply
with the behaviour of the current (to be obsoleted) code, thus should
the manual or the behaviour be adjusted?
END

View file

@ -112,11 +112,6 @@ ZEND_BEGIN_ARG_INFO(arginfo_iconv, 0)
ZEND_ARG_INFO(0, str) ZEND_ARG_INFO(0, str)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_ob_iconv_handler, 0)
ZEND_ARG_INFO(0, contents)
ZEND_ARG_INFO(0, status)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_iconv_set_encoding, 0) ZEND_BEGIN_ARG_INFO(arginfo_iconv_set_encoding, 0)
ZEND_ARG_INFO(0, type) ZEND_ARG_INFO(0, type)
ZEND_ARG_INFO(0, charset) ZEND_ARG_INFO(0, charset)
@ -132,7 +127,6 @@ ZEND_END_ARG_INFO()
*/ */
const zend_function_entry iconv_functions[] = { const zend_function_entry iconv_functions[] = {
PHP_RAW_NAMED_FE(iconv,php_if_iconv, arginfo_iconv) PHP_RAW_NAMED_FE(iconv,php_if_iconv, arginfo_iconv)
PHP_FE(ob_iconv_handler, arginfo_ob_iconv_handler)
PHP_FE(iconv_get_encoding, arginfo_iconv_get_encoding) PHP_FE(iconv_get_encoding, arginfo_iconv_get_encoding)
PHP_FE(iconv_set_encoding, arginfo_iconv_set_encoding) PHP_FE(iconv_set_encoding, arginfo_iconv_set_encoding)
PHP_FE(iconv_strlen, arginfo_iconv_strlen) PHP_FE(iconv_strlen, arginfo_iconv_strlen)
@ -214,6 +208,10 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st
static php_iconv_err_t php_iconv_stream_filter_register_factory(TSRMLS_D); static php_iconv_err_t php_iconv_stream_filter_register_factory(TSRMLS_D);
static php_iconv_err_t php_iconv_stream_filter_unregister_factory(TSRMLS_D); static php_iconv_err_t php_iconv_stream_filter_unregister_factory(TSRMLS_D);
static int php_iconv_output_conflict(const char *handler_name, size_t handler_name_len TSRMLS_DC);
static php_output_handler *php_iconv_output_handler_init(const char *name, size_t name_len, size_t chunk_size, int flags TSRMLS_DC);
static int php_iconv_output_handler(void **nothing, php_output_context *output_context);
/* }}} */ /* }}} */
/* {{{ static globals */ /* {{{ static globals */
@ -278,6 +276,9 @@ PHP_MINIT_FUNCTION(miconv)
return FAILURE; return FAILURE;
} }
php_output_handler_alias_register(ZEND_STRL("ob_iconv_handler"), php_iconv_output_handler_init TSRMLS_CC);
php_output_handler_conflict_register(ZEND_STRL("ob_iconv_handler"), php_iconv_output_conflict TSRMLS_CC);
return SUCCESS; return SUCCESS;
} }
/* }}} */ /* }}} */
@ -312,6 +313,62 @@ PHP_MINFO_FUNCTION(miconv)
} }
/* }}} */ /* }}} */
static int php_iconv_output_conflict(const char *handler_name, size_t handler_name_len TSRMLS_DC)
{
if (php_output_get_level(TSRMLS_C)) {
if (php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("ob_iconv_handler") TSRMLS_CC)
|| php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("mb_output_handler") TSRMLS_CC)) {
return FAILURE;
}
}
return SUCCESS;
}
static php_output_handler *php_iconv_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC)
{
return php_output_handler_create_internal(handler_name, handler_name_len, php_iconv_output_handler, chunk_size, flags TSRMLS_CC);
}
static int php_iconv_output_handler(void **nothing, php_output_context *output_context)
{
char *s, *content_type, *mimetype = NULL;
int output_status, mimetype_len = 0;
PHP_OUTPUT_TSRMLS(output_context);
if (output_context->op & PHP_OUTPUT_HANDLER_START) {
output_status = php_output_get_status(TSRMLS_C);
if (output_status & PHP_OUTPUT_SENT) {
return FAILURE;
}
if (SG(sapi_headers).mimetype && !strncasecmp(SG(sapi_headers).mimetype, "text/", 5)) {
if ((s = strchr(SG(sapi_headers).mimetype,';')) == NULL){
mimetype = SG(sapi_headers).mimetype;
} else {
mimetype = SG(sapi_headers).mimetype;
mimetype_len = s - SG(sapi_headers).mimetype;
}
} else if (SG(sapi_headers).send_default_content_type) {
mimetype = SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE;
}
if (mimetype != NULL && !(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) {
int len = spprintf(&content_type, 0, "Content-Type: %.*s; charset=%s", mimetype_len?mimetype_len:strlen(mimetype), mimetype, ICONVG(output_encoding));
if (content_type && SUCCESS == sapi_add_header(content_type, len, 0)) {
SG(sapi_headers).send_default_content_type = 0;
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
}
}
}
if (output_context->in.used) {
output_context->out.free = 1;
_php_iconv_show_error(php_iconv_string(output_context->in.data, output_context->in.used, &output_context->out.data, &output_context->out.used, ICONVG(output_encoding), ICONVG(internal_encoding)), ICONVG(output_encoding), ICONVG(internal_encoding) TSRMLS_CC);
}
return SUCCESS;
}
/* {{{ _php_iconv_appendl() */ /* {{{ _php_iconv_appendl() */
static php_iconv_err_t _php_iconv_appendl(smart_str *d, const char *s, size_t l, iconv_t cd) static php_iconv_err_t _php_iconv_appendl(smart_str *d, const char *s, size_t l, iconv_t cd)
{ {
@ -1131,7 +1188,7 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn
goto out; goto out;
} }
break; break;
default: default:
err = PHP_ICONV_ERR_UNKNOWN; err = PHP_ICONV_ERR_UNKNOWN;
goto out; goto out;
@ -1725,7 +1782,7 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st
break; break;
case '\n': case '\n':
scan_stat = 8; scan_stat = 8;
break; break;
case '=': /* first letter of an encoded chunk */ case '=': /* first letter of an encoded chunk */
@ -2308,58 +2365,6 @@ PHP_NAMED_FUNCTION(php_if_iconv)
} }
/* }}} */ /* }}} */
/* {{{ proto string ob_iconv_handler(string contents, int status)
Returns str in output buffer converted to the iconv.output_encoding character set */
PHP_FUNCTION(ob_iconv_handler)
{
char *out_buffer, *content_type, *mimetype = NULL, *s;
zval *zv_string;
size_t out_len;
int mimetype_alloced = 0;
long status;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &zv_string, &status) == FAILURE)
return;
convert_to_string(zv_string);
if (SG(sapi_headers).mimetype &&
strncasecmp(SG(sapi_headers).mimetype, "text/", 5) == 0) {
if ((s = strchr(SG(sapi_headers).mimetype,';')) == NULL){
mimetype = SG(sapi_headers).mimetype;
} else {
mimetype = estrndup(SG(sapi_headers).mimetype, s-SG(sapi_headers).mimetype);
mimetype_alloced = 1;
}
} else if (SG(sapi_headers).send_default_content_type) {
mimetype =(SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE);
}
if (mimetype != NULL) {
php_iconv_err_t err = php_iconv_string(Z_STRVAL_P(zv_string),
Z_STRLEN_P(zv_string), &out_buffer, &out_len,
ICONVG(output_encoding), ICONVG(internal_encoding));
_php_iconv_show_error(err, ICONVG(output_encoding), ICONVG(internal_encoding) TSRMLS_CC);
if (out_buffer != NULL) {
int len = spprintf(&content_type, 0, "Content-Type:%s; charset=%s", mimetype, ICONVG(output_encoding));
if (content_type && sapi_add_header(content_type, len, 0) != FAILURE) {
SG(sapi_headers).send_default_content_type = 0;
}
if (mimetype_alloced) {
efree(mimetype);
}
RETURN_STRINGL(out_buffer, out_len, 0);
}
if (mimetype_alloced) {
efree(mimetype);
}
}
zval_dtor(return_value);
*return_value = *zv_string;
zval_copy_ctor(return_value);
}
/* }}} */
/* {{{ proto bool iconv_set_encoding(string type, string charset) /* {{{ proto bool iconv_set_encoding(string type, string charset)
Sets internal encoding and output encoding for ob_iconv_handler() */ Sets internal encoding and output encoding for ob_iconv_handler() */
PHP_FUNCTION(iconv_set_encoding) PHP_FUNCTION(iconv_set_encoding)
@ -2488,7 +2493,7 @@ static int php_iconv_stream_filter_append_bucket(
char *pd, *pt; char *pd, *pt;
size_t ocnt, prev_ocnt, icnt, tcnt; size_t ocnt, prev_ocnt, icnt, tcnt;
size_t initial_out_buf_size; size_t initial_out_buf_size;
if (ps == NULL) { if (ps == NULL) {
initial_out_buf_size = 64; initial_out_buf_size = 64;
icnt = 1; icnt = 1;
@ -2784,7 +2789,7 @@ static php_stream_filter *php_iconv_stream_filter_factory_create(const char *nam
pefree(inst, persistent); pefree(inst, persistent);
} }
return retval; return retval;
} }
/* }}} */ /* }}} */

View file

@ -1093,8 +1093,8 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
if (PS(cache_limiter)[0] == '\0') return 0; if (PS(cache_limiter)[0] == '\0') return 0;
if (SG(headers_sent)) { if (SG(headers_sent)) {
char *output_start_filename = php_get_output_start_filename(TSRMLS_C); char *output_start_filename = php_output_get_start_filename(TSRMLS_C);
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C); int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);
if (output_start_filename) { if (output_start_filename) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)", output_start_filename, output_start_lineno); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)", output_start_filename, output_start_lineno);
@ -1133,8 +1133,8 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */
char *e_session_name, *e_id; char *e_session_name, *e_id;
if (SG(headers_sent)) { if (SG(headers_sent)) {
char *output_start_filename = php_get_output_start_filename(TSRMLS_C); char *output_start_filename = php_output_get_start_filename(TSRMLS_C);
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C); int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);
if (output_start_filename) { if (output_start_filename) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent by (output started at %s:%d)", output_start_filename, output_start_lineno); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cookie - headers already sent by (output started at %s:%d)", output_start_filename, output_start_lineno);

View file

@ -1650,7 +1650,7 @@ PHP_METHOD(SoapServer, handle)
ALLOC_INIT_ZVAL(retval); ALLOC_INIT_ZVAL(retval);
if (php_start_ob_buffer(NULL, 0, 0 TSRMLS_CC) != SUCCESS) { if (php_output_start_default(TSRMLS_C) != SUCCESS) {
php_error_docref(NULL TSRMLS_CC, E_ERROR,"ob_start failed"); php_error_docref(NULL TSRMLS_CC, E_ERROR,"ob_start failed");
} }
@ -1738,7 +1738,7 @@ PHP_METHOD(SoapServer, handle)
#ifdef ZEND_ENGINE_2 #ifdef ZEND_ENGINE_2
if (EG(exception)) { if (EG(exception)) {
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
if (Z_TYPE_P(EG(exception)) == IS_OBJECT && if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) { instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC); soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
@ -1792,7 +1792,7 @@ PHP_METHOD(SoapServer, handle)
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error calling constructor"); php_error_docref(NULL TSRMLS_CC, E_ERROR, "Error calling constructor");
} }
if (EG(exception)) { if (EG(exception)) {
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
if (Z_TYPE_P(EG(exception)) == IS_OBJECT && if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) { instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC); soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
@ -1824,7 +1824,7 @@ PHP_METHOD(SoapServer, handle)
} }
#ifdef ZEND_ENGINE_2 #ifdef ZEND_ENGINE_2
if (EG(exception)) { if (EG(exception)) {
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
if (Z_TYPE_P(EG(exception)) == IS_OBJECT && if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) { instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC); soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
@ -1904,14 +1904,14 @@ PHP_METHOD(SoapServer, handle)
Z_TYPE_PP(tmp) != IS_NULL) { Z_TYPE_PP(tmp) != IS_NULL) {
headerfault = *tmp; headerfault = *tmp;
} }
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
soap_server_fault_ex(function, &h->retval, h TSRMLS_CC); soap_server_fault_ex(function, &h->retval, h TSRMLS_CC);
efree(fn_name); efree(fn_name);
if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(&soap_obj);} if (service->type == SOAP_CLASS && soap_obj) {zval_ptr_dtor(&soap_obj);}
goto fail; goto fail;
#ifdef ZEND_ENGINE_2 #ifdef ZEND_ENGINE_2
} else if (EG(exception)) { } else if (EG(exception)) {
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
if (Z_TYPE_P(EG(exception)) == IS_OBJECT && if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) { instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
zval *headerfault = NULL, **tmp; zval *headerfault = NULL, **tmp;
@ -1961,7 +1961,7 @@ PHP_METHOD(SoapServer, handle)
#ifdef ZEND_ENGINE_2 #ifdef ZEND_ENGINE_2
if (EG(exception)) { if (EG(exception)) {
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
if (Z_TYPE_P(EG(exception)) == IS_OBJECT && if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) { instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC); soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
@ -1983,7 +1983,7 @@ PHP_METHOD(SoapServer, handle)
if (Z_TYPE_P(retval) == IS_OBJECT && if (Z_TYPE_P(retval) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(retval), soap_fault_class_entry TSRMLS_CC)) { instanceof_function(Z_OBJCE_P(retval), soap_fault_class_entry TSRMLS_CC)) {
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
soap_server_fault_ex(function, retval, NULL TSRMLS_CC); soap_server_fault_ex(function, retval, NULL TSRMLS_CC);
goto fail; goto fail;
} }
@ -2004,7 +2004,7 @@ PHP_METHOD(SoapServer, handle)
#ifdef ZEND_ENGINE_2 #ifdef ZEND_ENGINE_2
if (EG(exception)) { if (EG(exception)) {
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
if (Z_TYPE_P(EG(exception)) == IS_OBJECT && if (Z_TYPE_P(EG(exception)) == IS_OBJECT &&
instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) { instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) {
soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC); soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
@ -2023,7 +2023,7 @@ PHP_METHOD(SoapServer, handle)
#endif #endif
/* Flush buffer */ /* Flush buffer */
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
if (doc_return) { if (doc_return) {
/* xmlDocDumpMemoryEnc(doc_return, &buf, &size, XML_CHAR_ENCODING_UTF8); */ /* xmlDocDumpMemoryEnc(doc_return, &buf, &size, XML_CHAR_ENCODING_UTF8); */
@ -2041,39 +2041,14 @@ PHP_METHOD(SoapServer, handle)
xmlFreeDoc(doc_return); xmlFreeDoc(doc_return);
if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0) && if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
zend_hash_exists(EG(function_table), "ob_gzhandler", sizeof("ob_gzhandler"))) { sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1);
zval nm_ob_gzhandler; } else {
zval str;
zval mode;
zval result;
zval *params[2];
INIT_ZVAL(result);
ZVAL_STRINGL(&nm_ob_gzhandler, "ob_gzhandler", sizeof("ob_gzhandler") - 1, 0);
INIT_PZVAL(&str);
ZVAL_STRINGL(&str, (char*)buf, size, 0);
params[0] = &str;
INIT_PZVAL(&mode);
ZVAL_LONG(&mode, PHP_OUTPUT_HANDLER_START | PHP_OUTPUT_HANDLER_END);
params[1] = &mode;
if (call_user_function(CG(function_table), NULL, &nm_ob_gzhandler, &result, 2, params TSRMLS_CC) != FAILURE &&
Z_TYPE(result) == IS_STRING &&
zend_alter_ini_entry("zlib.output_compression", sizeof("zlib.output_compression"), "0", sizeof("0")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == SUCCESS) {
xmlFree(buf);
buf = NULL;
snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", Z_STRLEN(result));
sapi_add_header(cont_len, strlen(cont_len), 1);
php_write(Z_STRVAL(result), Z_STRLEN(result) TSRMLS_CC);
}
zval_dtor(&result);
}
if (buf) {
snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size); snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size);
sapi_add_header(cont_len, strlen(cont_len), 1); sapi_add_header(cont_len, strlen(cont_len), 1);
php_write(buf, size TSRMLS_CC);
xmlFree(buf);
} }
php_write(buf, size TSRMLS_CC);
xmlFree(buf);
} else { } else {
sapi_add_header("HTTP/1.1 202 Accepted", sizeof("HTTP/1.1 202 Accepted")-1, 1); sapi_add_header("HTTP/1.1 202 Accepted", sizeof("HTTP/1.1 202 Accepted")-1, 1);
sapi_add_header("Content-Length: 0", sizeof("Content-Length: 0")-1, 1); sapi_add_header("Content-Length: 0", sizeof("Content-Length: 0")-1, 1);
@ -2212,47 +2187,22 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade
if (use_http_error_status) { if (use_http_error_status) {
sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error")-1, 1); sapi_add_header("HTTP/1.1 500 Internal Service Error", sizeof("HTTP/1.1 500 Internal Service Error")-1, 1);
} }
if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1);
} else {
snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size);
sapi_add_header(cont_len, strlen(cont_len), 1);
}
if (soap_version == SOAP_1_2) { if (soap_version == SOAP_1_2) {
sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1); sapi_add_header("Content-Type: application/soap+xml; charset=utf-8", sizeof("Content-Type: application/soap+xml; charset=utf-8")-1, 1);
} else { } else {
sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1); sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
} }
if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0) && php_write(buf, size TSRMLS_CC);
zend_hash_exists(EG(function_table), "ob_gzhandler", sizeof("ob_gzhandler"))) {
zval nm_ob_gzhandler;
zval str;
zval mode;
zval result;
zval *params[2];
INIT_ZVAL(result);
ZVAL_STRINGL(&nm_ob_gzhandler, "ob_gzhandler", sizeof("ob_gzhandler") - 1, 0);
INIT_PZVAL(&str);
ZVAL_STRINGL(&str, (char*)buf, size, 0);
params[0] = &str;
INIT_PZVAL(&mode);
ZVAL_LONG(&mode, PHP_OUTPUT_HANDLER_START | PHP_OUTPUT_HANDLER_END);
params[1] = &mode;
if (call_user_function(CG(function_table), NULL, &nm_ob_gzhandler, &result, 2, params TSRMLS_CC) != FAILURE &&
Z_TYPE(result) == IS_STRING &&
zend_alter_ini_entry("zlib.output_compression", sizeof("zlib.output_compression"), "0", sizeof("0")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME) == SUCCESS) {
xmlFree(buf);
buf = NULL;
snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", Z_STRLEN(result));
sapi_add_header(cont_len, strlen(cont_len), 1);
php_write(Z_STRVAL(result), Z_STRLEN(result) TSRMLS_CC);
}
zval_dtor(&result);
}
if (buf) {
snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size);
sapi_add_header(cont_len, strlen(cont_len), 1);
php_write(buf, size TSRMLS_CC);
xmlFree(buf);
}
xmlFreeDoc(doc_return); xmlFreeDoc(doc_return);
xmlFree(buf);
zend_clear_exception(TSRMLS_C); zend_clear_exception(TSRMLS_C);
} }
@ -2415,11 +2365,11 @@ static void soap_error_handler(int error_num, const char *error_filename, const
} }
/* Get output buffer and send as fault detials */ /* Get output buffer and send as fault detials */
if (php_ob_get_length(&outbuflen TSRMLS_CC) != FAILURE && Z_LVAL(outbuflen) != 0) { if (php_output_get_length(&outbuflen TSRMLS_CC) != FAILURE && Z_LVAL(outbuflen) != 0) {
ALLOC_INIT_ZVAL(outbuf); ALLOC_INIT_ZVAL(outbuf);
php_ob_get_buffer(outbuf TSRMLS_CC); php_output_get_contents(outbuf TSRMLS_CC);
} }
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
} }
INIT_ZVAL(fault_obj); INIT_ZVAL(fault_obj);

View file

@ -5055,7 +5055,7 @@ ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini *syntax_highl
PHP_FUNCTION(highlight_file) PHP_FUNCTION(highlight_file)
{ {
char *filename; char *filename;
int filename_len; int filename_len, ret;
zend_syntax_highlighter_ini syntax_highlighter_ini; zend_syntax_highlighter_ini syntax_highlighter_ini;
zend_bool i = 0; zend_bool i = 0;
@ -5068,32 +5068,23 @@ PHP_FUNCTION(highlight_file)
} }
if (i) { if (i) {
php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); php_output_start_default(TSRMLS_C);
} }
php_get_highlight_struct(&syntax_highlighter_ini); php_get_highlight_struct(&syntax_highlighter_ini);
if (highlight_file(filename, &syntax_highlighter_ini TSRMLS_CC) == FAILURE) { ret = highlight_file(filename, &syntax_highlighter_ini TSRMLS_CC);
if (i) {
int res = php_ob_get_buffer(return_value TSRMLS_CC);
/* flush the buffer only if there is something to flush */ if (ret == FAILURE) {
if (res == SUCCESS && Z_STRLEN_P(return_value) > 0) { if (i) {
php_end_ob_buffer (1, 0 TSRMLS_CC); php_output_end(TSRMLS_C);
zval_dtor(return_value);
} else {
php_end_ob_buffer (0, 0 TSRMLS_CC);
if (res == SUCCESS) {
zval_dtor(return_value);
}
}
} }
RETURN_FALSE; RETURN_FALSE;
} }
if (i) { if (i) {
php_ob_get_buffer (return_value TSRMLS_CC); php_output_get_contents(return_value TSRMLS_CC);
php_end_ob_buffer (0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
} else { } else {
RETURN_TRUE; RETURN_TRUE;
} }
@ -5113,25 +5104,26 @@ PHP_FUNCTION(php_strip_whitespace)
RETURN_FALSE; RETURN_FALSE;
} }
php_output_start_default(TSRMLS_C);
file_handle.type = ZEND_HANDLE_FILENAME; file_handle.type = ZEND_HANDLE_FILENAME;
file_handle.filename = filename; file_handle.filename = filename;
file_handle.free_filename = 0; file_handle.free_filename = 0;
file_handle.opened_path = NULL; file_handle.opened_path = NULL;
zend_save_lexical_state(&original_lex_state TSRMLS_CC); zend_save_lexical_state(&original_lex_state TSRMLS_CC);
if (open_file_for_scanning(&file_handle TSRMLS_CC)==FAILURE) { if (open_file_for_scanning(&file_handle TSRMLS_CC) == FAILURE) {
zend_restore_lexical_state(&original_lex_state TSRMLS_CC); zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
php_output_end(TSRMLS_C);
RETURN_EMPTY_STRING(); RETURN_EMPTY_STRING();
} }
php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
zend_strip(TSRMLS_C); zend_strip(TSRMLS_C);
zend_destroy_file_handle(&file_handle TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC);
zend_restore_lexical_state(&original_lex_state TSRMLS_CC); zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
php_ob_get_buffer(return_value TSRMLS_CC); php_output_get_contents(return_value TSRMLS_CC);
php_end_ob_buffer(0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
} }
/* }}} */ /* }}} */
@ -5151,7 +5143,7 @@ PHP_FUNCTION(highlight_string)
convert_to_string_ex(expr); convert_to_string_ex(expr);
if (i) { if (i) {
php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); php_output_start_default(TSRMLS_C);
} }
EG(error_reporting) = E_ERROR; EG(error_reporting) = E_ERROR;
@ -5164,7 +5156,7 @@ PHP_FUNCTION(highlight_string)
efree(hicompiled_string_description); efree(hicompiled_string_description);
EG(error_reporting) = old_error_reporting; EG(error_reporting) = old_error_reporting;
if (i) { if (i) {
php_end_ob_buffer (1, 0 TSRMLS_CC); php_output_end(TSRMLS_C);
} }
RETURN_FALSE; RETURN_FALSE;
} }
@ -5173,8 +5165,8 @@ PHP_FUNCTION(highlight_string)
EG(error_reporting) = old_error_reporting; EG(error_reporting) = old_error_reporting;
if (i) { if (i) {
php_ob_get_buffer (return_value TSRMLS_CC); php_output_get_contents(return_value TSRMLS_CC);
php_end_ob_buffer (0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
} else { } else {
RETURN_TRUE; RETURN_TRUE;
} }
@ -5416,14 +5408,14 @@ PHP_FUNCTION(print_r)
} }
if (do_return) { if (do_return) {
php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); php_output_start_default(TSRMLS_C);
} }
zend_print_zval_r(var, 0 TSRMLS_CC); zend_print_zval_r(var, 0 TSRMLS_CC);
if (do_return) { if (do_return) {
php_ob_get_buffer (return_value TSRMLS_CC); php_output_get_contents(return_value TSRMLS_CC);
php_end_ob_buffer (0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
} else { } else {
RETURN_TRUE; RETURN_TRUE;
} }

View file

@ -108,8 +108,10 @@ PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value TSRMLS_
} }
if (type == 1) { if (type == 1) {
int ob_level;
PHPWRITE(buf, bufl); PHPWRITE(buf, bufl);
if (OG(ob_nesting_level) < 1) { if (php_output_get_level(TSRMLS_C) < 1) {
sapi_flush(TSRMLS_C); sapi_flush(TSRMLS_C);
} }
} else if (type == 2) { } else if (type == 2) {

View file

@ -228,8 +228,8 @@ PHP_FUNCTION(headers_sent)
return; return;
if (SG(headers_sent)) { if (SG(headers_sent)) {
line = php_get_output_start_lineno(TSRMLS_C); line = php_output_get_start_lineno(TSRMLS_C);
file = php_get_output_start_filename(TSRMLS_C); file = php_output_get_start_filename(TSRMLS_C);
} }
switch(ZEND_NUM_ARGS()) { switch(ZEND_NUM_ARGS()) {

View file

@ -38,16 +38,15 @@
#include <sys/utsname.h> #include <sys/utsname.h>
#endif #endif
#ifdef PHP_WIN32 #ifdef PHP_WIN32
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
# include "winver.h" # include "winver.h"
#if _MSC_VER < 1300 # if _MSC_VER < 1300
# define OSVERSIONINFOEX php_win_OSVERSIONINFOEX # define OSVERSIONINFOEX php_win_OSVERSIONINFOEX
#endif # endif
#endif #endif
#if HAVE_MBSTRING #if HAVE_MBSTRING
@ -61,7 +60,7 @@ ZEND_EXTERN_MODULE_GLOBALS(iconv)
#endif #endif
#define SECTION(name) if (!sapi_module.phpinfo_as_text) { \ #define SECTION(name) if (!sapi_module.phpinfo_as_text) { \
PUTS("<h2>" name "</h2>\n"); \ php_info_print("<h2>" name "</h2>\n"); \
} else { \ } else { \
php_info_print_table_start(); \ php_info_print_table_start(); \
php_info_print_table_header(1, name); \ php_info_print_table_header(1, name); \
@ -71,29 +70,99 @@ ZEND_EXTERN_MODULE_GLOBALS(iconv)
PHPAPI extern char *php_ini_opened_path; PHPAPI extern char *php_ini_opened_path;
PHPAPI extern char *php_ini_scanned_path; PHPAPI extern char *php_ini_scanned_path;
PHPAPI extern char *php_ini_scanned_files; PHPAPI extern char *php_ini_scanned_files;
static int php_info_write_wrapper(const char *str, uint str_length) static int php_info_print_html_esc(const char *str, int len) /* {{{ */
{ {
int new_len, written; int new_len, written;
char *elem_esc; char *new_str;
TSRMLS_FETCH(); TSRMLS_FETCH();
elem_esc = php_escape_html_entities((unsigned char *)str, str_length, &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC); new_str = php_escape_html_entities((char *) str, len, &new_len, 0, ENT_QUOTES, "utf-8" TSRMLS_CC);
written = php_output_write(new_str, new_len TSRMLS_CC);
written = php_body_write(elem_esc, new_len TSRMLS_CC); efree(new_str);
efree(elem_esc);
return written; return written;
} }
/* }}} */
static int php_info_printf(const char *fmt, ...) /* {{{ */
{
char *buf;
int len, written;
va_list argv;
TSRMLS_FETCH();
va_start(argv, fmt);
len = vspprintf(&buf, 0, fmt, argv);
va_end(argv);
written = php_output_write(buf, len TSRMLS_CC);
efree(buf);
return written;
}
/* }}} */
static void php_info_print_request_uri(TSRMLS_D) /* {{{ */
{
if (SG(request_info).request_uri) {
php_info_print_html_esc(SG(request_info).request_uri, strlen(SG(request_info).request_uri));
}
}
/* }}} */
static int php_info_print(const char *str) /* {{{ */
{
TSRMLS_FETCH();
return php_output_write(str, strlen(str) TSRMLS_CC);
}
/* }}} */
static void php_info_print_stream_hash(const char *name, HashTable *ht TSRMLS_DC) /* {{{ */
{
char *key;
uint len;
int type;
if (ht) {
if (zend_hash_num_elements(ht)) {
HashPosition pos;
if (!sapi_module.phpinfo_as_text) {
php_info_printf("<tr class=\"v\"><td>Registered %s</td><td>", name);
} else {
php_info_printf("\nRegistered %s => ", name);
}
zend_hash_internal_pointer_reset_ex(ht, &pos);
while (zend_hash_get_current_key_ex(ht, &key, &len, NULL, 0, &pos) == HASH_KEY_IS_STRING)
{
php_info_print(key);
zend_hash_move_forward_ex(ht, &pos);
if (zend_hash_get_current_key_ex(ht, &key, &len, NULL, 0, &pos) == HASH_KEY_IS_STRING) {
php_info_print(", ");
} else {
break;
}
}
if (!sapi_module.phpinfo_as_text) {
php_info_print("</td></tr>\n");
}
} else {
char reg_name[128];
snprintf(reg_name, sizeof(reg_name), "Registered %s", name);
php_info_print_table_row(2, reg_name, "none registered");
}
} else {
php_info_print_table_row(2, name, "disabled");
}
}
/* }}} */
PHPAPI void php_info_print_module(zend_module_entry *zend_module TSRMLS_DC) /* {{{ */ PHPAPI void php_info_print_module(zend_module_entry *zend_module TSRMLS_DC) /* {{{ */
{ {
if (zend_module->info_func || zend_module->version) { if (zend_module->info_func || zend_module->version) {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<h2><a name=\"module_%s\">%s</a></h2>\n", zend_module->name, zend_module->name); php_info_printf("<h2><a name=\"module_%s\">%s</a></h2>\n", zend_module->name, zend_module->name);
} else { } else {
php_info_print_table_start(); php_info_print_table_start();
php_info_print_table_header(1, zend_module->name); php_info_print_table_header(1, zend_module->name);
@ -109,9 +178,9 @@ PHPAPI void php_info_print_module(zend_module_entry *zend_module TSRMLS_DC) /* {
} }
} else { } else {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<tr><td>%s</td></tr>\n", zend_module->name); php_info_printf("<tr><td>%s</td></tr>\n", zend_module->name);
} else { } else {
php_printf("%s\n", zend_module->name); php_info_printf("%s\n", zend_module->name);
} }
} }
} }
@ -151,70 +220,66 @@ static void php_print_gpcse_array(char *name, uint name_length TSRMLS_DC)
zend_hash_internal_pointer_reset(Z_ARRVAL_PP(data)); zend_hash_internal_pointer_reset(Z_ARRVAL_PP(data));
while (zend_hash_get_current_data(Z_ARRVAL_PP(data), (void **) &tmp) == SUCCESS) { while (zend_hash_get_current_data(Z_ARRVAL_PP(data), (void **) &tmp) == SUCCESS) {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
PUTS("<tr>"); php_info_print("<tr>");
PUTS("<td class=\"e\">"); php_info_print("<td class=\"e\">");
} }
PUTS(name); php_info_print(name);
PUTS("[\""); php_info_print("[\"");
switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(data), &string_key, &string_len, &num_key, 0, NULL)) { switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(data), &string_key, &string_len, &num_key, 0, NULL)) {
case HASH_KEY_IS_STRING: case HASH_KEY_IS_STRING:
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_info_html_esc_write(string_key, string_len - 1 TSRMLS_CC); php_info_print_html_esc(string_key, string_len-1);
} else { } else {
PHPWRITE(string_key, string_len - 1); php_info_print(string_key);
} }
break; break;
case HASH_KEY_IS_LONG: case HASH_KEY_IS_LONG:
php_printf("%ld", num_key); php_info_printf("%ld", num_key);
break; break;
} }
PUTS("\"]"); php_info_print("\"]");
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
PUTS("</td><td class=\"v\">"); php_info_print("</td><td class=\"v\">");
} else { } else {
PUTS(" => "); php_info_print(" => ");
} }
if (Z_TYPE_PP(tmp) == IS_ARRAY) { if (Z_TYPE_PP(tmp) == IS_ARRAY) {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
PUTS("<pre>"); php_info_print("<pre>");
zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC); zend_print_zval_r_ex((zend_write_func_t) php_info_print_html_esc, *tmp, 0 TSRMLS_CC);
PUTS("</pre>"); php_info_print("</pre>");
} else { } else {
zend_print_zval_r(*tmp, 0 TSRMLS_CC); zend_print_zval_r(*tmp, 0 TSRMLS_CC);
} }
} else if (Z_TYPE_PP(tmp) != IS_STRING) {
tmp2 = **tmp;
zval_copy_ctor(&tmp2);
convert_to_string(&tmp2);
if (!sapi_module.phpinfo_as_text) {
if (Z_STRLEN(tmp2) == 0) {
PUTS("<i>no value</i>");
} else {
php_info_html_esc_write(Z_STRVAL(tmp2), Z_STRLEN(tmp2) TSRMLS_CC);
}
} else {
PHPWRITE(Z_STRVAL(tmp2), Z_STRLEN(tmp2));
}
zval_dtor(&tmp2);
} else { } else {
if (!sapi_module.phpinfo_as_text) { tmp2 = **tmp;
if (Z_STRLEN_PP(tmp) == 0) { switch (Z_TYPE_PP(tmp)) {
PUTS("<i>no value</i>"); default:
} else { tmp = NULL;
php_info_html_esc_write(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp) TSRMLS_CC); zval_copy_ctor(&tmp2);
} convert_to_string(&tmp2);
} else { case IS_STRING:
PHPWRITE(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); if (!sapi_module.phpinfo_as_text) {
} if (Z_STRLEN(tmp2) == 0) {
php_info_print("<i>no value</i>");
} else {
php_info_print_html_esc(Z_STRVAL(tmp2), Z_STRLEN(tmp2));
}
} else {
php_info_print(Z_STRVAL(tmp2));
}
}
if (!tmp) {
zval_dtor(&tmp2);
}
} }
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
PUTS("</td></tr>\n"); php_info_print("</td></tr>\n");
} else { } else {
PUTS("\n"); php_info_print("\n");
} }
zend_hash_move_forward(Z_ARRVAL_PP(data)); zend_hash_move_forward(Z_ARRVAL_PP(data));
} }
} }
@ -225,21 +290,9 @@ static void php_print_gpcse_array(char *name, uint name_length TSRMLS_DC)
*/ */
void php_info_print_style(TSRMLS_D) void php_info_print_style(TSRMLS_D)
{ {
php_printf("<style type=\"text/css\">\n"); php_info_printf("<style type=\"text/css\">\n");
php_info_print_css(TSRMLS_C); php_info_print_css(TSRMLS_C);
php_printf("</style>\n"); php_info_printf("</style>\n");
}
/* }}} */
/* {{{ php_info_html_esc_write
*/
PHPAPI void php_info_html_esc_write(char *string, int str_len TSRMLS_DC)
{
int new_len;
char *ret = php_escape_html_entities((unsigned char *)string, str_len, &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
PHPWRITE(ret, new_len);
efree(ret);
} }
/* }}} */ /* }}} */
@ -248,13 +301,13 @@ PHPAPI void php_info_html_esc_write(char *string, int str_len TSRMLS_DC)
PHPAPI char *php_info_html_esc(char *string TSRMLS_DC) PHPAPI char *php_info_html_esc(char *string TSRMLS_DC)
{ {
int new_len; int new_len;
return php_escape_html_entities((unsigned char *)string, strlen(string), &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC); return php_escape_html_entities(string, strlen(string), &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
} }
/* }}} */ /* }}} */
#ifdef PHP_WIN32 #ifdef PHP_WIN32
/* {{{ */ /* {{{ */
char* php_get_windows_name() char* php_get_windows_name()
{ {
OSVERSIONINFOEX osvi; OSVERSIONINFOEX osvi;
@ -360,9 +413,9 @@ char* php_get_windows_name()
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) { if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) {
if (GetSystemMetrics(SM_SERVERR2)) if (GetSystemMetrics(SM_SERVERR2))
major = "Windows Server 2003 R2"; major = "Windows Server 2003 R2";
else if (osvi.wSuiteMask == VER_SUITE_STORAGE_SERVER) else if (osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER)
major = "Windows Storage Server 2003"; major = "Windows Storage Server 2003";
else if (osvi.wSuiteMask == VER_SUITE_WH_SERVER) else if (osvi.wSuiteMask==VER_SUITE_WH_SERVER)
major = "Windows Home Server"; major = "Windows Home Server";
else if (osvi.wProductType == VER_NT_WORKSTATION && else if (osvi.wProductType == VER_NT_WORKSTATION &&
si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) { si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) {
@ -588,54 +641,18 @@ PHPAPI char *php_get_uname(char mode)
} }
/* }}} */ /* }}} */
/* {{{ php_print_info_htmlhead /* {{{ php_print_info_htmlhead
*/ */
PHPAPI void php_print_info_htmlhead(TSRMLS_D) PHPAPI void php_print_info_htmlhead(TSRMLS_D)
{ {
php_info_print("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\">\n");
/*** none of this is needed now *** php_info_print("<html>");
php_info_print("<head>\n");
const char *charset = NULL;
if (SG(default_charset)) {
charset = SG(default_charset);
}
#if HAVE_MBSTRING
if (php_ob_handler_used("mb_output_handler" TSRMLS_CC)) {
if (MBSTRG(current_http_output_encoding) == mbfl_no_encoding_pass) {
charset = "US-ASCII";
} else {
charset = mbfl_no2preferred_mime_name(MBSTRG(current_http_output_encoding));
}
}
#endif
#if HAVE_ICONV
if (php_ob_handler_used("ob_iconv_handler" TSRMLS_CC)) {
charset = ICONVG(output_encoding);
}
#endif
if (!charset || !charset[0]) {
charset = "US-ASCII";
}
*** none of that is needed now ***/
PUTS("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\">\n");
PUTS("<html>");
PUTS("<head>\n");
php_info_print_style(TSRMLS_C); php_info_print_style(TSRMLS_C);
PUTS("<title>phpinfo()</title>"); php_info_print("<title>phpinfo()</title>");
PUTS("<meta name=\"ROBOTS\" content=\"NOINDEX,NOFOLLOW,NOARCHIVE\" />"); php_info_print("<meta name=\"ROBOTS\" content=\"NOINDEX,NOFOLLOW,NOARCHIVE\" />");
/* php_info_print("</head>\n");
php_printf("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\" />\n", charset); php_info_print("<body><div class=\"center\">\n");
*/
PUTS("</head>\n");
PUTS("<body><div class=\"center\">\n");
} }
/* }}} */ /* }}} */
@ -661,8 +678,8 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_print_info_htmlhead(TSRMLS_C); php_print_info_htmlhead(TSRMLS_C);
} else { } else {
PUTS("phpinfo()\n"); php_info_print("phpinfo()\n");
} }
if (flag & PHP_INFO_GENERAL) { if (flag & PHP_INFO_GENERAL) {
char *zend_version = get_zend_version(); char *zend_version = get_zend_version();
@ -676,21 +693,17 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
} }
if (expose_php && !sapi_module.phpinfo_as_text) { if (expose_php && !sapi_module.phpinfo_as_text) {
PUTS("<a href=\"http://www.php.net/\"><img border=\"0\" src=\""); php_info_print("<a href=\"http://www.php.net/\"><img border=\"0\" src=\"");
if (SG(request_info).request_uri) { php_info_print_request_uri(TSRMLS_C);
char *elem_esc = php_info_html_esc(SG(request_info).request_uri TSRMLS_CC); php_info_print("?=");
PUTS(elem_esc);
efree(elem_esc);
}
PUTS("?=");
logo_guid = php_logo_guid(); logo_guid = php_logo_guid();
PUTS(logo_guid); php_info_print(logo_guid);
efree(logo_guid); efree(logo_guid);
PUTS("\" alt=\"PHP Logo\" /></a>"); php_info_print("\" alt=\"PHP Logo\" /></a>");
} }
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION); php_info_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
} else { } else {
php_info_print_table_row(2, "PHP Version", PHP_VERSION); php_info_print_table_row(2, "PHP Version", PHP_VERSION);
} }
@ -766,139 +779,24 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
#else #else
php_info_print_table_row(2, "DTrace Support", "disabled" ); php_info_print_table_row(2, "DTrace Support", "disabled" );
#endif #endif
{
HashTable *url_stream_wrappers_hash;
char *stream_protocol, *stream_protocols_buf = NULL;
int stream_protocol_len, stream_protocols_buf_len = 0;
ulong num_key;
if ((url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash())) {
HashPosition pos;
for (zend_hash_internal_pointer_reset_ex(url_stream_wrappers_hash, &pos);
zend_hash_get_current_key_ex(url_stream_wrappers_hash, &stream_protocol, (uint *)&stream_protocol_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING;
zend_hash_move_forward_ex(url_stream_wrappers_hash, &pos)) {
stream_protocols_buf = erealloc(stream_protocols_buf, stream_protocols_buf_len + stream_protocol_len + 2 + 1);
memcpy(stream_protocols_buf + stream_protocols_buf_len, stream_protocol, stream_protocol_len - 1);
stream_protocols_buf[stream_protocols_buf_len + stream_protocol_len - 1] = ',';
stream_protocols_buf[stream_protocols_buf_len + stream_protocol_len] = ' ';
stream_protocols_buf_len += stream_protocol_len + 1;
}
if (stream_protocols_buf) {
stream_protocols_buf[stream_protocols_buf_len - 2] = ' ';
stream_protocols_buf[stream_protocols_buf_len] = 0;
php_info_print_table_row(2, "Registered PHP Streams", stream_protocols_buf);
efree(stream_protocols_buf);
} else {
/* Any chances we will ever hit this? */
php_info_print_table_row(2, "Registered PHP Streams", "no streams registered");
}
} else {
/* Any chances we will ever hit this? */
php_info_print_table_row(2, "PHP Streams", "disabled"); /* ?? */
}
}
{
HashTable *stream_xport_hash;
char *xport_name, *xport_buf = NULL;
int xport_name_len, xport_buf_len = 0, xport_buf_size = 0;
ulong num_key;
if ((stream_xport_hash = php_stream_xport_get_hash())) {
HashPosition pos;
for(zend_hash_internal_pointer_reset_ex(stream_xport_hash, &pos);
zend_hash_get_current_key_ex(stream_xport_hash, &xport_name, (uint *)&xport_name_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING;
zend_hash_move_forward_ex(stream_xport_hash, &pos)) {
if (xport_buf_len + xport_name_len + 2 > xport_buf_size) {
while (xport_buf_len + xport_name_len + 2 > xport_buf_size) {
xport_buf_size += 256;
}
if (xport_buf) {
xport_buf = erealloc(xport_buf, xport_buf_size);
} else {
xport_buf = emalloc(xport_buf_size);
}
}
if (xport_buf_len > 0) {
xport_buf[xport_buf_len++] = ',';
xport_buf[xport_buf_len++] = ' ';
}
memcpy(xport_buf + xport_buf_len, xport_name, xport_name_len - 1);
xport_buf_len += xport_name_len - 1;
xport_buf[xport_buf_len] = '\0';
}
if (xport_buf) {
php_info_print_table_row(2, "Registered Stream Socket Transports", xport_buf);
efree(xport_buf);
} else {
/* Any chances we will ever hit this? */
php_info_print_table_row(2, "Registered Stream Socket Transports", "no transports registered");
}
} else {
/* Any chances we will ever hit this? */
php_info_print_table_row(2, "Stream Socket Transports", "disabled"); /* ?? */
}
}
{
HashTable *stream_filter_hash;
char *filter_name, *filter_buf = NULL;
int filter_name_len, filter_buf_len = 0, filter_buf_size = 0;
ulong num_key;
if ((stream_filter_hash = php_get_stream_filters_hash())) {
HashPosition pos;
for(zend_hash_internal_pointer_reset_ex(stream_filter_hash, &pos);
zend_hash_get_current_key_ex(stream_filter_hash, &filter_name, (uint *)&filter_name_len, &num_key, 0, &pos) == HASH_KEY_IS_STRING;
zend_hash_move_forward_ex(stream_filter_hash, &pos)) {
if (filter_buf_len + filter_name_len + 2 > filter_buf_size) {
while (filter_buf_len + filter_name_len + 2 > filter_buf_size) {
filter_buf_size += 256;
}
if (filter_buf) {
filter_buf = erealloc(filter_buf, filter_buf_size);
} else {
filter_buf = emalloc(filter_buf_size);
}
}
if (filter_buf_len > 0) {
filter_buf[filter_buf_len++] = ',';
filter_buf[filter_buf_len++] = ' ';
}
memcpy(filter_buf + filter_buf_len, filter_name, filter_name_len - 1);
filter_buf_len += filter_name_len - 1;
filter_buf[filter_buf_len] = '\0';
}
if (filter_buf) {
php_info_print_table_row(2, "Registered Stream Filters", filter_buf);
efree(filter_buf);
} else {
/* Any chances we will ever hit this? */
php_info_print_table_row(2, "Registered Stream Filters", "no filters registered");
}
} else {
/* Any chances we will ever hit this? */
php_info_print_table_row(2, "Stream Filters", "disabled"); /* ?? */
}
}
php_info_print_stream_hash("PHP Streams", php_stream_get_url_stream_wrappers_hash() TSRMLS_CC);
php_info_print_stream_hash("Stream Socket Transports", php_stream_xport_get_hash() TSRMLS_CC);
php_info_print_stream_hash("Stream Filters", php_get_stream_filters_hash() TSRMLS_CC);
php_info_print_table_end(); php_info_print_table_end();
/* Zend Engine */ /* Zend Engine */
php_info_print_box_start(0); php_info_print_box_start(0);
if (expose_php && !sapi_module.phpinfo_as_text) { if (expose_php && !sapi_module.phpinfo_as_text) {
PUTS("<a href=\"http://www.zend.com/\"><img border=\"0\" src=\""); php_info_print("<a href=\"http://www.zend.com/\"><img border=\"0\" src=\"");
if (SG(request_info).request_uri) { php_info_print_request_uri(TSRMLS_C);
char *elem_esc = php_info_html_esc(SG(request_info).request_uri TSRMLS_CC); php_info_print("?="ZEND_LOGO_GUID"\" alt=\"Zend logo\" /></a>\n");
PUTS(elem_esc);
efree(elem_esc);
}
PUTS("?="ZEND_LOGO_GUID"\" alt=\"Zend logo\" /></a>\n");
} }
PUTS("This program makes use of the Zend Scripting Language Engine:"); php_info_print("This program makes use of the Zend Scripting Language Engine:");
PUTS(!sapi_module.phpinfo_as_text?"<br />":"\n"); php_info_print(!sapi_module.phpinfo_as_text?"<br />":"\n");
if (sapi_module.phpinfo_as_text) { if (sapi_module.phpinfo_as_text) {
PUTS(zend_version); php_info_print(zend_version);
} else { } else {
zend_html_puts(zend_version, strlen(zend_version) TSRMLS_CC); zend_html_puts(zend_version, strlen(zend_version) TSRMLS_CC);
} }
@ -908,15 +806,11 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
if ((flag & PHP_INFO_CREDITS) && expose_php && !sapi_module.phpinfo_as_text) { if ((flag & PHP_INFO_CREDITS) && expose_php && !sapi_module.phpinfo_as_text) {
php_info_print_hr(); php_info_print_hr();
PUTS("<h1><a href=\""); php_info_print("<h1><a href=\"");
if (SG(request_info).request_uri) { php_info_print_request_uri(TSRMLS_C);
char *elem_esc = php_info_html_esc(SG(request_info).request_uri TSRMLS_CC); php_info_print("?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000\">");
PUTS(elem_esc); php_info_print("PHP Credits");
efree(elem_esc); php_info_print("</a></h1>\n");
}
PUTS("?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000\">");
PUTS("PHP Credits");
PUTS("</a></h1>\n");
} }
zend_ini_sort_entries(TSRMLS_C); zend_ini_sort_entries(TSRMLS_C);
@ -924,7 +818,7 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
if (flag & PHP_INFO_CONFIGURATION) { if (flag & PHP_INFO_CONFIGURATION) {
php_info_print_hr(); php_info_print_hr();
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
PUTS("<h1>Configuration</h1>\n"); php_info_print("<h1>Configuration</h1>\n");
} else { } else {
SECTION("Configuration"); SECTION("Configuration");
} }
@ -1004,103 +898,108 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
SECTION("PHP License"); SECTION("PHP License");
php_info_print_box_start(0); php_info_print_box_start(0);
PUTS("<p>\n"); php_info_print("<p>\n");
PUTS("This program is free software; you can redistribute it and/or modify "); php_info_print("This program is free software; you can redistribute it and/or modify ");
PUTS("it under the terms of the PHP License as published by the PHP Group "); php_info_print("it under the terms of the PHP License as published by the PHP Group ");
PUTS("and included in the distribution in the file: LICENSE\n"); php_info_print("and included in the distribution in the file: LICENSE\n");
PUTS("</p>\n"); php_info_print("</p>\n");
PUTS("<p>"); php_info_print("<p>");
PUTS("This program is distributed in the hope that it will be useful, "); php_info_print("This program is distributed in the hope that it will be useful, ");
PUTS("but WITHOUT ANY WARRANTY; without even the implied warranty of "); php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of ");
PUTS("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
PUTS("</p>\n"); php_info_print("</p>\n");
PUTS("<p>"); php_info_print("<p>");
PUTS("If you did not receive a copy of the PHP license, or have any questions about "); php_info_print("If you did not receive a copy of the PHP license, or have any questions about ");
PUTS("PHP licensing, please contact license@php.net.\n"); php_info_print("PHP licensing, please contact license@php.net.\n");
PUTS("</p>\n"); php_info_print("</p>\n");
php_info_print_box_end(); php_info_print_box_end();
} else { } else {
PUTS("\nPHP License\n"); php_info_print("\nPHP License\n");
PUTS("This program is free software; you can redistribute it and/or modify\n"); php_info_print("This program is free software; you can redistribute it and/or modify\n");
PUTS("it under the terms of the PHP License as published by the PHP Group\n"); php_info_print("it under the terms of the PHP License as published by the PHP Group\n");
PUTS("and included in the distribution in the file: LICENSE\n"); php_info_print("and included in the distribution in the file: LICENSE\n");
PUTS("\n"); php_info_print("\n");
PUTS("This program is distributed in the hope that it will be useful,\n"); php_info_print("This program is distributed in the hope that it will be useful,\n");
PUTS("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
PUTS("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
PUTS("\n"); php_info_print("\n");
PUTS("If you did not receive a copy of the PHP license, or have any\n"); php_info_print("If you did not receive a copy of the PHP license, or have any\n");
PUTS("questions about PHP licensing, please contact license@php.net.\n"); php_info_print("questions about PHP licensing, please contact license@php.net.\n");
} }
} }
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
PUTS("</div></body></html>"); php_info_print("</div></body></html>");
} }
} }
/* }}} */ /* }}} */
PHPAPI void php_info_print_table_start(void) /* {{{ */
PHPAPI void php_info_print_table_start(void)
{ {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<table border=\"0\" cellpadding=\"3\" width=\"600\">\n"); php_info_print("<table border=\"0\" cellpadding=\"3\" width=\"600\">\n");
} else { } else {
php_printf("\n"); php_info_print("\n");
} }
} }
/* }}} */
PHPAPI void php_info_print_table_end(void) PHPAPI void php_info_print_table_end(void) /* {{{ */
{ {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("</table><br />\n"); php_info_print("</table><br />\n");
} }
} }
/* }}} */
PHPAPI void php_info_print_box_start(int flag) PHPAPI void php_info_print_box_start(int flag) /* {{{ */
{ {
php_info_print_table_start(); php_info_print_table_start();
if (flag) { if (flag) {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<tr class=\"h\"><td>\n"); php_info_print("<tr class=\"h\"><td>\n");
} }
} else { } else {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<tr class=\"v\"><td>\n"); php_info_print("<tr class=\"v\"><td>\n");
} else { } else {
php_printf("\n"); php_info_print("\n");
} }
} }
} }
/* }}} */
PHPAPI void php_info_print_box_end(void) PHPAPI void php_info_print_box_end(void) /* {{{ */
{ {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("</td></tr>\n"); php_info_print("</td></tr>\n");
} }
php_info_print_table_end(); php_info_print_table_end();
} }
/* }}} */
PHPAPI void php_info_print_hr(void) PHPAPI void php_info_print_hr(void) /* {{{ */
{ {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<hr />\n"); php_info_print("<hr />\n");
} else { } else {
php_printf("\n\n _______________________________________________________________________\n\n"); php_info_print("\n\n _______________________________________________________________________\n\n");
} }
} }
/* }}} */
PHPAPI void php_info_print_table_colspan_header(int num_cols, char *header) PHPAPI void php_info_print_table_colspan_header(int num_cols, char *header) /* {{{ */
{ {
int spaces; int spaces;
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<tr class=\"h\"><th colspan=\"%d\">%s</th></tr>\n", num_cols, header ); php_info_printf("<tr class=\"h\"><th colspan=\"%d\">%s</th></tr>\n", num_cols, header );
} else { } else {
spaces = (74 - strlen(header)); spaces = (74 - strlen(header));
php_printf("%*s%s%*s\n", (int)(spaces/2), " ", header, (int)(spaces/2), " "); php_info_printf("%*s%s%*s\n", (int)(spaces/2), " ", header, (int)(spaces/2), " ");
} }
} }
/* }}} */
/* {{{ php_info_print_table_header /* {{{ php_info_print_table_header
*/ */
@ -1110,11 +1009,9 @@ PHPAPI void php_info_print_table_header(int num_cols, ...)
va_list row_elements; va_list row_elements;
char *row_element; char *row_element;
TSRMLS_FETCH();
va_start(row_elements, num_cols); va_start(row_elements, num_cols);
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<tr class=\"h\">"); php_info_print("<tr class=\"h\">");
} }
for (i=0; i<num_cols; i++) { for (i=0; i<num_cols; i++) {
row_element = va_arg(row_elements, char *); row_element = va_arg(row_elements, char *);
@ -1122,21 +1019,21 @@ PHPAPI void php_info_print_table_header(int num_cols, ...)
row_element = " "; row_element = " ";
} }
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
PUTS("<th>"); php_info_print("<th>");
PUTS(row_element); php_info_print(row_element);
PUTS("</th>"); php_info_print("</th>");
} else { } else {
PUTS(row_element); php_info_print(row_element);
if (i < num_cols-1) { if (i < num_cols-1) {
PUTS(" => "); php_info_print(" => ");
} else { } else {
PUTS("\n"); php_info_print("\n");
} }
} }
} }
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("</tr>\n"); php_info_print("</tr>\n");
} }
va_end(row_elements); va_end(row_elements);
} }
@ -1149,49 +1046,41 @@ static void php_info_print_table_row_internal(int num_cols,
{ {
int i; int i;
char *row_element; char *row_element;
char *elem_esc = NULL;
/*
int elem_esc_len;
*/
TSRMLS_FETCH();
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<tr>"); php_info_print("<tr>");
} }
for (i=0; i<num_cols; i++) { for (i=0; i<num_cols; i++) {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("<td class=\"%s\">", php_info_printf("<td class=\"%s\">",
(i==0 ? "e" : value_class ) (i==0 ? "e" : value_class )
); );
} }
row_element = va_arg(row_elements, char *); row_element = va_arg(row_elements, char *);
if (!row_element || !*row_element) { if (!row_element || !*row_element) {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
PUTS( "<i>no value</i>" ); php_info_print( "<i>no value</i>" );
} else { } else {
PUTS( " " ); php_info_print( " " );
} }
} else { } else {
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
elem_esc = php_info_html_esc(row_element TSRMLS_CC); php_info_print_html_esc(row_element, strlen(row_element));
PUTS(elem_esc);
efree(elem_esc);
} else { } else {
PUTS(row_element); php_info_print(row_element);
if (i < num_cols-1) { if (i < num_cols-1) {
PUTS(" => "); php_info_print(" => ");
} }
} }
} }
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf(" </td>"); php_info_print(" </td>");
} else if (i == (num_cols - 1)) { } else if (i == (num_cols - 1)) {
PUTS("\n"); php_info_print("\n");
} }
} }
if (!sapi_module.phpinfo_as_text) { if (!sapi_module.phpinfo_as_text) {
php_printf("</tr>\n"); php_info_print("</tr>\n");
} }
} }
/* }}} */ /* }}} */
@ -1255,9 +1144,9 @@ PHP_FUNCTION(phpinfo)
} }
/* Andale! Andale! Yee-Hah! */ /* Andale! Andale! Yee-Hah! */
php_start_ob_buffer(NULL, 4096, 0 TSRMLS_CC); php_output_start_default(TSRMLS_C);
php_print_info(flag TSRMLS_CC); php_print_info(flag TSRMLS_CC);
php_end_ob_buffer(1, 0 TSRMLS_CC); php_output_end(TSRMLS_C);
RETURN_TRUE; RETURN_TRUE;
} }
@ -1268,20 +1157,18 @@ PHP_FUNCTION(phpinfo)
Return the current PHP version */ Return the current PHP version */
PHP_FUNCTION(phpversion) PHP_FUNCTION(phpversion)
{ {
zval **arg; char *ext_name = NULL;
const char *version; int ext_name_len = 0;
int argc = ZEND_NUM_ARGS();
if (argc == 0) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ext_name, &ext_name_len) == FAILURE) {
return;
}
if (!ext_name) {
RETURN_STRING(PHP_VERSION, 1); RETURN_STRING(PHP_VERSION, 1);
} else { } else {
if (zend_parse_parameters(argc TSRMLS_CC, "Z", &arg) == FAILURE) { const char *version;
return; version = zend_get_module_version(ext_name);
}
convert_to_string_ex(arg);
version = zend_get_module_version(Z_STRVAL_PP(arg));
if (version == NULL) { if (version == NULL) {
RETURN_FALSE; RETURN_FALSE;
} }
@ -1305,7 +1192,6 @@ PHP_FUNCTION(phpcredits)
} }
/* }}} */ /* }}} */
/* {{{ php_logo_guid /* {{{ php_logo_guid
*/ */
PHPAPI char *php_logo_guid(void) PHPAPI char *php_logo_guid(void)
@ -1333,7 +1219,6 @@ PHPAPI char *php_logo_guid(void)
Return the special ID used to request the PHP logo in phpinfo screens*/ Return the special ID used to request the PHP logo in phpinfo screens*/
PHP_FUNCTION(php_logo_guid) PHP_FUNCTION(php_logo_guid)
{ {
if (zend_parse_parameters_none() == FAILURE) { if (zend_parse_parameters_none() == FAILURE) {
return; return;
} }
@ -1346,7 +1231,6 @@ PHP_FUNCTION(php_logo_guid)
Return the special ID used to request the PHP logo in phpinfo screens*/ Return the special ID used to request the PHP logo in phpinfo screens*/
PHP_FUNCTION(php_real_logo_guid) PHP_FUNCTION(php_real_logo_guid)
{ {
if (zend_parse_parameters_none() == FAILURE) { if (zend_parse_parameters_none() == FAILURE) {
return; return;
} }
@ -1402,6 +1286,7 @@ PHP_FUNCTION(php_uname)
{ {
char *mode = "a"; char *mode = "a";
int modelen = sizeof("a")-1; int modelen = sizeof("a")-1;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &mode, &modelen) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &mode, &modelen) == FAILURE) {
return; return;
} }

View file

@ -26,5 +26,7 @@ var_dump( ob_get_flush() );
Warning: ob_get_flush() expects exactly 0 parameters, 1 given in %s on line %d Warning: ob_get_flush() expects exactly 0 parameters, 1 given in %s on line %d
NULL NULL
Notice: ob_get_flush(): failed to delete and flush buffer. No buffer to delete or flush in %s on line %d
bool(false) bool(false)
===DONE=== ===DONE===

View file

@ -1,8 +1,8 @@
/* Generated by re2c 0.13.5 on Mon Jul 27 02:20:40 2009 */ /* Generated by re2c 0.13.5 on Mon May 31 11:07:50 2010 */
#line 1 "ext/standard/url_scanner_ex.re" #line 1 "ext/standard/url_scanner_ex.re"
/* /*
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 6 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2006 The PHP Group | | Copyright (c) 1997-2006 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
@ -993,7 +993,7 @@ static void php_url_scanner_output_handler(char *output, uint output_len, char *
size_t len; size_t len;
if (BG(url_adapt_state_ex).url_app.len != 0) { if (BG(url_adapt_state_ex).url_app.len != 0) {
*handled_output = url_adapt_ext(output, output_len, &len, (zend_bool) (mode & (PHP_OUTPUT_HANDLER_END | PHP_OUTPUT_HANDLER_CONT) ? 1 : 0) TSRMLS_CC); *handled_output = url_adapt_ext(output, output_len, &len, (zend_bool) (mode & (PHP_OUTPUT_HANDLER_END | PHP_OUTPUT_HANDLER_CONT | PHP_OUTPUT_HANDLER_FLUSH | PHP_OUTPUT_HANDLER_FINAL) ? 1 : 0) TSRMLS_CC);
if (sizeof(uint) < sizeof(size_t)) { if (sizeof(uint) < sizeof(size_t)) {
if (len > UINT_MAX) if (len > UINT_MAX)
len = UINT_MAX; len = UINT_MAX;
@ -1027,7 +1027,7 @@ PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int va
if (! BG(url_adapt_state_ex).active) { if (! BG(url_adapt_state_ex).active) {
php_url_scanner_ex_activate(TSRMLS_C); php_url_scanner_ex_activate(TSRMLS_C);
php_ob_set_internal_handler(php_url_scanner_output_handler, 0, "URL-Rewriter", 1 TSRMLS_CC); php_output_start_internal(ZEND_STRL("URL-Rewriter"), php_url_scanner_output_handler, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
BG(url_adapt_state_ex).active = 1; BG(url_adapt_state_ex).active = 1;
} }

View file

@ -1,6 +1,6 @@
/* /*
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| PHP Version 5 | | PHP Version 6 |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Copyright (c) 1997-2006 The PHP Group | | Copyright (c) 1997-2006 The PHP Group |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
@ -431,7 +431,7 @@ static void php_url_scanner_output_handler(char *output, uint output_len, char *
size_t len; size_t len;
if (BG(url_adapt_state_ex).url_app.len != 0) { if (BG(url_adapt_state_ex).url_app.len != 0) {
*handled_output = url_adapt_ext(output, output_len, &len, (zend_bool) (mode & (PHP_OUTPUT_HANDLER_END | PHP_OUTPUT_HANDLER_CONT) ? 1 : 0) TSRMLS_CC); *handled_output = url_adapt_ext(output, output_len, &len, (zend_bool) (mode & (PHP_OUTPUT_HANDLER_END | PHP_OUTPUT_HANDLER_CONT | PHP_OUTPUT_HANDLER_FLUSH | PHP_OUTPUT_HANDLER_FINAL) ? 1 : 0) TSRMLS_CC);
if (sizeof(uint) < sizeof(size_t)) { if (sizeof(uint) < sizeof(size_t)) {
if (len > UINT_MAX) if (len > UINT_MAX)
len = UINT_MAX; len = UINT_MAX;
@ -465,7 +465,7 @@ PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int va
if (! BG(url_adapt_state_ex).active) { if (! BG(url_adapt_state_ex).active) {
php_url_scanner_ex_activate(TSRMLS_C); php_url_scanner_ex_activate(TSRMLS_C);
php_ob_set_internal_handler(php_url_scanner_output_handler, 0, "URL-Rewriter", 1 TSRMLS_CC); php_output_start_internal(ZEND_STRL("URL-Rewriter"), php_url_scanner_output_handler, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
BG(url_adapt_state_ex).active = 1; BG(url_adapt_state_ex).active = 1;
} }

View file

@ -456,14 +456,14 @@ PHP_FUNCTION(var_export)
} }
if (return_output) { if (return_output) {
php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC); php_output_start_default(TSRMLS_C);
} }
php_var_export(&var, 1 TSRMLS_CC); php_var_export(&var, 1 TSRMLS_CC);
if (return_output) { if (return_output) {
php_ob_get_buffer (return_value TSRMLS_CC); php_output_get_contents(return_value TSRMLS_CC);
php_end_ob_buffer (0, 0 TSRMLS_CC); php_output_discard(TSRMLS_C);
} }
} }
/* }}} */ /* }}} */

View file

@ -36,6 +36,7 @@ extern zend_module_entry tidy_module_entry;
ZEND_BEGIN_MODULE_GLOBALS(tidy) ZEND_BEGIN_MODULE_GLOBALS(tidy)
char *default_config; char *default_config;
zend_bool clean_output;
ZEND_END_MODULE_GLOBALS(tidy) ZEND_END_MODULE_GLOBALS(tidy)
#ifdef ZTS #ifdef ZTS

View file

@ -42,6 +42,8 @@
/* {{{ ext/tidy macros /* {{{ ext/tidy macros
*/ */
#define FIX_BUFFER(bptr) do { if ((bptr)->size) { (bptr)->bp[(bptr)->size-1] = '\0'; } } while(0)
#define TIDY_SET_CONTEXT \ #define TIDY_SET_CONTEXT \
zval *object = getThis(); zval *object = getThis();
@ -186,16 +188,16 @@ typedef enum {
} tidy_base_nodetypes; } tidy_base_nodetypes;
struct _PHPTidyDoc { struct _PHPTidyDoc {
TidyDoc doc; TidyDoc doc;
TidyBuffer *errbuf; TidyBuffer *errbuf;
unsigned int ref_count; unsigned int ref_count;
}; };
struct _PHPTidyObj { struct _PHPTidyObj {
zend_object std; zend_object std;
TidyNode node; TidyNode node;
tidy_obj_type type; tidy_obj_type type;
PHPTidyDoc *ptdoc; PHPTidyDoc *ptdoc;
}; };
/* }}} */ /* }}} */
@ -216,6 +218,10 @@ static int _php_tidy_set_tidy_opt(TidyDoc, char *, zval * TSRMLS_DC);
static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC); static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC);
static void _php_tidy_register_nodetypes(INIT_FUNC_ARGS); static void _php_tidy_register_nodetypes(INIT_FUNC_ARGS);
static void _php_tidy_register_tags(INIT_FUNC_ARGS); static void _php_tidy_register_tags(INIT_FUNC_ARGS);
static PHP_INI_MH(php_tidy_set_clean_output);
static void php_tidy_clean_output_start(const char *name, size_t name_len TSRMLS_DC);
static php_output_handler *php_tidy_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC);
static int php_tidy_output_handler(void **nothing, php_output_context *output_context);
static PHP_MINIT_FUNCTION(tidy); static PHP_MINIT_FUNCTION(tidy);
static PHP_MSHUTDOWN_FUNCTION(tidy); static PHP_MSHUTDOWN_FUNCTION(tidy);
@ -245,8 +251,6 @@ static PHP_FUNCTION(tidy_warning_count);
static PHP_FUNCTION(tidy_access_count); static PHP_FUNCTION(tidy_access_count);
static PHP_FUNCTION(tidy_config_count); static PHP_FUNCTION(tidy_config_count);
static PHP_FUNCTION(ob_tidyhandler);
static PHP_FUNCTION(tidy_get_root); static PHP_FUNCTION(tidy_get_root);
static PHP_FUNCTION(tidy_get_html); static PHP_FUNCTION(tidy_get_html);
static PHP_FUNCTION(tidy_get_head); static PHP_FUNCTION(tidy_get_head);
@ -271,8 +275,8 @@ static TIDY_NODE_METHOD(__construct);
ZEND_DECLARE_MODULE_GLOBALS(tidy) ZEND_DECLARE_MODULE_GLOBALS(tidy)
PHP_INI_BEGIN() PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("tidy.default_config", "", PHP_INI_SYSTEM, OnUpdateString, default_config, zend_tidy_globals, tidy_globals) STD_PHP_INI_ENTRY("tidy.default_config", "", PHP_INI_SYSTEM, OnUpdateString, default_config, zend_tidy_globals, tidy_globals)
PHP_INI_ENTRY("tidy.clean_output", "0", PHP_INI_PERDIR, NULL) STD_PHP_INI_ENTRY("tidy.clean_output", "0", PHP_INI_USER, php_tidy_set_clean_output, clean_output, zend_tidy_globals, tidy_globals)
PHP_INI_END() PHP_INI_END()
/* {{{ arginfo */ /* {{{ arginfo */
@ -282,8 +286,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_parse_string, 0, 0, 1)
ZEND_ARG_INFO(0, encoding) ZEND_ARG_INFO(0, encoding)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_error_buffer, 0, 0, 0) ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_error_buffer, 0)
ZEND_ARG_INFO(0, detailed)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_output, 0) ZEND_BEGIN_ARG_INFO(arginfo_tidy_get_output, 0)
@ -368,11 +371,6 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_body, 0, 0, 1) ZEND_BEGIN_ARG_INFO_EX(arginfo_tidy_get_body, 0, 0, 1)
ZEND_ARG_INFO(0, tidy) ZEND_ARG_INFO(0, tidy)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_ob_tidyhandler, 0, 0, 1)
ZEND_ARG_INFO(0, input)
ZEND_ARG_INFO(0, mode)
ZEND_END_ARG_INFO()
/* }}} */ /* }}} */
static const zend_function_entry tidy_functions[] = { static const zend_function_entry tidy_functions[] = {
@ -402,7 +400,6 @@ static const zend_function_entry tidy_functions[] = {
PHP_FE(tidy_get_head, arginfo_tidy_get_head) PHP_FE(tidy_get_head, arginfo_tidy_get_head)
PHP_FE(tidy_get_html, arginfo_tidy_get_html) PHP_FE(tidy_get_html, arginfo_tidy_get_html)
PHP_FE(tidy_get_body, arginfo_tidy_get_body) PHP_FE(tidy_get_body, arginfo_tidy_get_body)
PHP_FE(ob_tidyhandler, arginfo_ob_tidyhandler)
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };
@ -605,7 +602,7 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
TidyBuffer buf; TidyBuffer buf;
tidyBufInit(&buf); tidyBufInit(&buf);
tidyBufAppend(&buf, data, data_len); tidyBufAttach(&buf, (byte *) data, data_len);
if (tidyParseBuffer(doc, &buf) < 0) { if (tidyParseBuffer(doc, &buf) < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf->bp); php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf->bp);
@ -616,20 +613,19 @@ static void php_tidy_quick_repair(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_fil
tidyBufInit(&output); tidyBufInit(&output);
tidySaveBuffer (doc, &output); tidySaveBuffer (doc, &output);
RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1); FIX_BUFFER(&output);
RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0, 1);
tidyBufFree(&output); tidyBufFree(&output);
} else { } else {
RETVAL_FALSE; RETVAL_FALSE;
} }
} }
tidyBufFree(&buf);
} }
if (is_file) { if (is_file) {
efree(data); efree(data);
} }
tidyBufFree(errbuf); tidyBufFree(errbuf);
efree(errbuf); efree(errbuf);
tidyRelease(doc); tidyRelease(doc);
@ -643,7 +639,7 @@ static char *php_tidy_file_to_mem(char *filename, zend_bool use_include_path, in
if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0), NULL))) { if (!(stream = php_stream_open_wrapper(filename, "rb", (use_include_path ? USE_PATH : 0), NULL))) {
return NULL; return NULL;
} }
if ((*len = (int) php_stream_copy_to_mem(stream, &data, PHP_STREAM_COPY_ALL, 0)) == 0) { if ((*len = (int) php_stream_copy_to_mem(stream, (void*) &data, PHP_STREAM_COPY_ALL, 0)) == 0) {
data = estrdup(""); data = estrdup("");
*len = 0; *len = 0;
} }
@ -687,11 +683,6 @@ static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *
break; break;
case is_doc: case is_doc:
tidySetMallocCall(php_tidy_malloc);
tidySetReallocCall(php_tidy_realloc);
tidySetFreeCall(php_tidy_free);
tidySetPanicCall(php_tidy_panic);
intern->ptdoc = emalloc(sizeof(PHPTidyDoc)); intern->ptdoc = emalloc(sizeof(PHPTidyDoc));
intern->ptdoc->doc = tidyCreate(); intern->ptdoc->doc = tidyCreate();
intern->ptdoc->ref_count = 1; intern->ptdoc->ref_count = 1;
@ -714,9 +705,6 @@ static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers *
tidy_add_default_properties(intern, is_doc TSRMLS_CC); tidy_add_default_properties(intern, is_doc TSRMLS_CC);
break; break;
default:
break;
} }
retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) tidy_object_free_storage, NULL TSRMLS_CC); retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) tidy_object_free_storage, NULL TSRMLS_CC);
@ -772,7 +760,7 @@ static int tidy_doc_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC); obj = (PHPTidyObj *)zend_object_store_get_object(in TSRMLS_CC);
tidyBufInit(&output); tidyBufInit(&output);
tidySaveBuffer (obj->ptdoc->doc, &output); tidySaveBuffer (obj->ptdoc->doc, &output);
ZVAL_STRINGL(out, (char*)output.bp, output.size ? output.size-1 : 0, TRUE); ZVAL_STRINGL(out, (char *) output.bp, output.size ? output.size-1 : 0, 1);
tidyBufFree(&output); tidyBufFree(&output);
break; break;
@ -806,8 +794,10 @@ static int tidy_node_cast_handler(zval *in, zval *out, int type TSRMLS_DC)
tidyBufInit(&buf); tidyBufInit(&buf);
if (obj->ptdoc) { if (obj->ptdoc) {
tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
ZVAL_STRINGL(out, (char *) buf.bp, buf.size-1, 1);
} else {
ZVAL_EMPTY_STRING(out);
} }
ZVAL_STRINGL(out, (char*)buf.bp, buf.size ? buf.size-1 : 0, TRUE);
tidyBufFree(&buf); tidyBufFree(&buf);
break; break;
@ -865,7 +855,7 @@ static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type TSRM
} }
tidyBufInit(&buf); tidyBufInit(&buf);
tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf); tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
ADD_PROPERTY_STRINGL(obj->std.properties, value, buf.bp, buf.size-1); ADD_PROPERTY_STRINGL(obj->std.properties, value, buf.bp, buf.size ? buf.size-1 : 0);
tidyBufFree(&buf); tidyBufFree(&buf);
ADD_PROPERTY_STRING(obj->std.properties, name, tidyNodeGetName(obj->node)); ADD_PROPERTY_STRING(obj->std.properties, name, tidyNodeGetName(obj->node));
@ -1009,24 +999,33 @@ static void php_tidy_create_node(INTERNAL_FUNCTION_PARAMETERS, tidy_base_nodetyp
static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC) static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRMLS_DC)
{ {
char *opt_name = NULL; char *opt_name;
zval **opt_val; zval **opt_val;
ulong opt_indx; ulong opt_indx;
uint opt_name_len;
zend_bool clear_str;
for (zend_hash_internal_pointer_reset(ht_options); for (zend_hash_internal_pointer_reset(ht_options);
zend_hash_get_current_data(ht_options, (void **)&opt_val) == SUCCESS; zend_hash_get_current_data(ht_options, (void *) &opt_val) == SUCCESS;
zend_hash_move_forward(ht_options)) { zend_hash_move_forward(ht_options)) {
if(zend_hash_get_current_key(ht_options, &opt_name, &opt_indx, FALSE) == FAILURE) { switch (zend_hash_get_current_key_ex(ht_options, &opt_name, &opt_name_len, &opt_indx, FALSE, NULL)) {
case HASH_KEY_IS_STRING:
clear_str = 0;
break;
case HASH_KEY_IS_LONG:
continue; /* ignore numeric keys */
default:
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not retrieve key from option array"); php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not retrieve key from option array");
return FAILURE; return FAILURE;
} }
if(opt_name) { _php_tidy_set_tidy_opt(doc, opt_name, *opt_val TSRMLS_CC);
_php_tidy_set_tidy_opt(doc, opt_name, *opt_val TSRMLS_CC); if (clear_str) {
opt_name = NULL; efree(opt_name);
} }
} }
return SUCCESS; return SUCCESS;
@ -1035,7 +1034,7 @@ static int _php_tidy_apply_config_array(TidyDoc doc, HashTable *ht_options TSRML
static int php_tidy_parse_string(PHPTidyObj *obj, char *string, int len, char *enc TSRMLS_DC) static int php_tidy_parse_string(PHPTidyObj *obj, char *string, int len, char *enc TSRMLS_DC)
{ {
TidyBuffer buf; TidyBuffer buf;
if(enc) { if(enc) {
if (tidySetCharEncoding(obj->ptdoc->doc, enc) < 0) { if (tidySetCharEncoding(obj->ptdoc->doc, enc) < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", enc); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not set encoding '%s'", enc);
@ -1044,14 +1043,11 @@ static int php_tidy_parse_string(PHPTidyObj *obj, char *string, int len, char *e
} }
tidyBufInit(&buf); tidyBufInit(&buf);
tidyBufAppend(&buf, string, len); tidyBufAttach(&buf, (byte *) string, len);
if (tidyParseBuffer(obj->ptdoc->doc, &buf) < 0) { if (tidyParseBuffer(obj->ptdoc->doc, &buf) < 0) {
tidyBufFree(&buf);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", obj->ptdoc->errbuf->bp); php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", obj->ptdoc->errbuf->bp);
return FAILURE; return FAILURE;
} }
tidyBufFree(&buf);
tidy_doc_update_properties(obj TSRMLS_CC); tidy_doc_update_properties(obj TSRMLS_CC);
return SUCCESS; return SUCCESS;
@ -1059,6 +1055,11 @@ static int php_tidy_parse_string(PHPTidyObj *obj, char *string, int len, char *e
static PHP_MINIT_FUNCTION(tidy) static PHP_MINIT_FUNCTION(tidy)
{ {
tidySetMallocCall(php_tidy_malloc);
tidySetReallocCall(php_tidy_realloc);
tidySetFreeCall(php_tidy_free);
tidySetPanicCall(php_tidy_panic);
REGISTER_INI_ENTRIES(); REGISTER_INI_ENTRIES();
REGISTER_TIDY_CLASS(tidy, doc, NULL, 0); REGISTER_TIDY_CLASS(tidy, doc, NULL, 0);
REGISTER_TIDY_CLASS(tidyNode, node, NULL, ZEND_ACC_FINAL_CLASS); REGISTER_TIDY_CLASS(tidyNode, node, NULL, ZEND_ACC_FINAL_CLASS);
@ -1069,16 +1070,14 @@ static PHP_MINIT_FUNCTION(tidy)
_php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU); _php_tidy_register_tags(INIT_FUNC_ARGS_PASSTHRU);
_php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU); _php_tidy_register_nodetypes(INIT_FUNC_ARGS_PASSTHRU);
php_output_handler_alias_register(ZEND_STRL("ob_tidyhandler"), php_tidy_output_handler_init TSRMLS_CC);
return SUCCESS; return SUCCESS;
} }
static PHP_RINIT_FUNCTION(tidy) static PHP_RINIT_FUNCTION(tidy)
{ {
if (INI_BOOL("tidy.clean_output") == TRUE) { php_tidy_clean_output_start(ZEND_STRL("ob_tidyhandler") TSRMLS_CC);
if (php_start_ob_buffer_named("ob_tidyhandler", 0, 1 TSRMLS_CC) == FAILURE) {
zend_error(E_NOTICE, "Failure installing Tidy output buffering.");
}
}
return SUCCESS; return SUCCESS;
} }
@ -1100,59 +1099,106 @@ static PHP_MINFO_FUNCTION(tidy)
DISPLAY_INI_ENTRIES(); DISPLAY_INI_ENTRIES();
} }
static PHP_FUNCTION(ob_tidyhandler) static PHP_INI_MH(php_tidy_set_clean_output)
{ {
char *input; int status;
int input_len; zend_bool value;
long mode;
TidyBuffer errbuf;
TidyDoc doc;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &input, &input_len, &mode) == FAILURE) { if (new_value_length==2 && strcasecmp("on", new_value)==0) {
return; value = (zend_bool) 1;
} else if (new_value_length==3 && strcasecmp("yes", new_value)==0) {
value = (zend_bool) 1;
} else if (new_value_length==4 && strcasecmp("true", new_value)==0) {
value = (zend_bool) 1;
} else {
value = (zend_bool) atoi(new_value);
} }
doc = tidyCreate(); if (stage == PHP_INI_STAGE_RUNTIME) {
tidyBufInit(&errbuf); status = php_output_get_status(TSRMLS_C);
tidyOptSetBool(doc, TidyForceOutput, yes); if (value && (status & PHP_OUTPUT_WRITTEN)) {
tidyOptSetBool(doc, TidyMark, no); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot enable tidy.clean_output - there has already been output");
return FAILURE;
}
if (status & PHP_OUTPUT_SENT) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot change tidy.clean_output - headers already sent");
return FAILURE;
}
}
status = OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
if (stage == PHP_INI_STAGE_RUNTIME && value) {
if (!php_output_handler_started(ZEND_STRL("ob_tidyhandler") TSRMLS_CC)) {
php_tidy_clean_output_start(ZEND_STRL("ob_tidyhandler") TSRMLS_CC);
}
}
return status;
}
/*
* NOTE: tidy does not support iterative/cumulative parsing, so chunk-sized output handler is not possible
*/
static void php_tidy_clean_output_start(const char *name, size_t name_len TSRMLS_DC)
{
php_output_handler *h;
if (TG(clean_output) && (h = php_tidy_output_handler_init(name, name_len, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC))) {
php_output_handler_start(h TSRMLS_CC);
}
}
static php_output_handler *php_tidy_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC)
{
if (chunk_size) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot use a chunk size for ob_tidyhandler");
return NULL;
}
if (!TG(clean_output)) {
TG(clean_output) = 1;
}
return php_output_handler_create_internal(handler_name, handler_name_len, php_tidy_output_handler, chunk_size, flags TSRMLS_CC);
}
static int php_tidy_output_handler(void **nothing, php_output_context *output_context)
{
int status = FAILURE;
TidyDoc doc;
TidyBuffer inbuf, outbuf, errbuf;
PHP_OUTPUT_TSRMLS(output_context);
if (TG(clean_output) && (output_context->op & PHP_OUTPUT_HANDLER_START) && (output_context->op & PHP_OUTPUT_HANDLER_FINAL)) {
doc = tidyCreate();
tidyBufInit(&errbuf);
if (0 == tidySetErrorBuffer(doc, &errbuf)) {
tidyOptSetBool(doc, TidyForceOutput, yes);
tidyOptSetBool(doc, TidyMark, no);
TIDY_SET_DEFAULT_CONFIG(doc);
tidyBufInit(&inbuf);
tidyBufAttach(&inbuf, (byte *) output_context->in.data, output_context->in.used);
if (0 <= tidyParseBuffer(doc, &inbuf) && 0 <= tidyCleanAndRepair(doc)) {
tidyBufInit(&outbuf);
tidySaveBuffer(doc, &outbuf);
FIX_BUFFER(&outbuf);
output_context->out.data = (char *) outbuf.bp;
output_context->out.used = outbuf.size ? outbuf.size-1 : 0;
output_context->out.free = 1;
status = SUCCESS;
}
}
if (tidySetErrorBuffer(doc, &errbuf) != 0) {
tidyRelease(doc); tidyRelease(doc);
tidyBufFree(&errbuf); tidyBufFree(&errbuf);
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not set Tidy error buffer");
} }
TIDY_SET_DEFAULT_CONFIG(doc); return status;
if (input_len > 1) {
TidyBuffer buf;
tidyBufInit(&buf);
tidyBufAppend(&buf, input, input_len);
if (tidyParseBuffer(doc, &buf) < 0 || tidyCleanAndRepair(doc) < 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errbuf.bp);
RETVAL_NULL();
} else {
TidyBuffer output;
tidyBufInit(&output);
tidySaveBuffer(doc, &output);
RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1);
tidyBufFree(&output);
}
tidyBufFree(&buf);
} else {
RETVAL_NULL();
}
tidyRelease(doc);
tidyBufFree(&errbuf);
} }
/* {{{ proto bool tidy_parse_string(string input [, mixed config_options [, string encoding]]) /* {{{ proto bool tidy_parse_string(string input [, mixed config_options [, string encoding]])
@ -1162,7 +1208,6 @@ static PHP_FUNCTION(tidy_parse_string)
char *input, *enc = NULL; char *input, *enc = NULL;
int input_len, enc_len = 0; int input_len, enc_len = 0;
zval **options = NULL; zval **options = NULL;
PHPTidyObj *obj; PHPTidyObj *obj;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Zs", &input, &input_len, &options, &enc, &enc_len) == FAILURE) {
@ -1179,11 +1224,10 @@ static PHP_FUNCTION(tidy_parse_string)
INIT_ZVAL(*return_value); INIT_ZVAL(*return_value);
RETURN_FALSE; RETURN_FALSE;
} }
} }
/* }}} */ /* }}} */
/* {{{ proto string tidy_get_error_buffer([boolean detailed]) /* {{{ proto string tidy_get_error_buffer()
Return warnings and errors which occured parsing the specified document*/ Return warnings and errors which occured parsing the specified document*/
static PHP_FUNCTION(tidy_get_error_buffer) static PHP_FUNCTION(tidy_get_error_buffer)
{ {
@ -1206,9 +1250,8 @@ static PHP_FUNCTION(tidy_get_output)
tidyBufInit(&output); tidyBufInit(&output);
tidySaveBuffer(obj->ptdoc->doc, &output); tidySaveBuffer(obj->ptdoc->doc, &output);
FIX_BUFFER(&output);
RETVAL_STRINGL((char*)output.bp, output.size ? output.size-1 : 0, 1); RETVAL_STRINGL((char *) output.bp, output.size ? output.size-1 : 0, 1);
tidyBufFree(&output); tidyBufFree(&output);
} }
/* }}} */ /* }}} */
@ -1234,7 +1277,7 @@ static PHP_FUNCTION(tidy_parse_file)
obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC); obj = (PHPTidyObj *) zend_object_store_get_object(return_value TSRMLS_CC);
if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) { if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : ""); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : "");
RETURN_FALSE; RETURN_FALSE;
} }
@ -1315,7 +1358,7 @@ static PHP_FUNCTION(tidy_get_release)
static PHP_FUNCTION(tidy_get_opt_doc) static PHP_FUNCTION(tidy_get_opt_doc)
{ {
PHPTidyObj *obj; PHPTidyObj *obj;
char *optname, *optval; char *optval, *optname;
int optname_len; int optname_len;
TidyOption opt; TidyOption opt;
@ -1351,7 +1394,7 @@ static PHP_FUNCTION(tidy_get_opt_doc)
/* {{{ proto array tidy_get_config() /* {{{ proto array tidy_get_config()
Get current Tidy configuarion */ Get current Tidy configuration */
static PHP_FUNCTION(tidy_get_config) static PHP_FUNCTION(tidy_get_config)
{ {
TidyIterator itOpt; TidyIterator itOpt;
@ -1548,7 +1591,7 @@ static TIDY_DOC_METHOD(__construct)
if (inputfile) { if (inputfile) {
if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) { if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : ""); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : "");
return; return;
} }
@ -1579,7 +1622,7 @@ static TIDY_DOC_METHOD(parseFile)
} }
if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) { if (!(contents = php_tidy_file_to_mem(inputfile, use_include_path, &contents_len TSRMLS_CC))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory %s", inputfile, (use_include_path) ? "(Using include path)" : ""); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot Load '%s' into memory%s", inputfile, (use_include_path) ? " (Using include path)" : "");
RETURN_FALSE; RETURN_FALSE;
} }
@ -1786,6 +1829,7 @@ static TIDY_NODE_METHOD(getParent)
} }
/* }}} */ /* }}} */
/* {{{ proto void tidyNode::__construct() /* {{{ proto void tidyNode::__construct()
__constructor for tidyNode. */ __constructor for tidyNode. */
static TIDY_NODE_METHOD(__construct) static TIDY_NODE_METHOD(__construct)

View file

@ -1,2 +1,2 @@
Zlib Zlib
Rasmus Lerdorf, Stefan Roehrich, Zeev Suraski, Jade Nicoletti Rasmus Lerdorf, Stefan Roehrich, Zeev Suraski, Jade Nicoletti, Michael Wallner

View file

@ -41,10 +41,17 @@ if test "$PHP_ZLIB" != "no" || test "$PHP_ZLIB_DIR" != "no"; then
*) ac_extra=-L$ZLIB_DIR/$PHP_LIBDIR ;; *) ac_extra=-L$ZLIB_DIR/$PHP_LIBDIR ;;
esac esac
AC_MSG_CHECKING([for zlib version >= 1.2.0.4])
ZLIB_VERSION=`$EGREP "define ZLIB_VERSION" $ZLIB_DIR/include/zlib.h | $SED -e 's/[[^0-9\.]]//g'`
AC_MSG_RESULT([$ZLIB_VERSION])
if test `echo $ZLIB_VERSION | $SED -e 's/[[^0-9]]/ /g' | $AWK '{print $1*1000000 + $2*10000 + $3*100 + $4}'` -lt 1020004; then
AC_MSG_ERROR([libz version greater or equal to 1.2.0.4 required])
fi
PHP_CHECK_LIBRARY(z, gzgets, [ PHP_CHECK_LIBRARY(z, gzgets, [
AC_DEFINE(HAVE_ZLIB,1,[ ]) AC_DEFINE(HAVE_ZLIB,1,[ ])
],[ ],[
AC_MSG_ERROR(ZLIB extension requires zlib >= 1.0.9) AC_MSG_ERROR(ZLIB extension requires gzgets in zlib)
],[ ],[
$ac_extra $ac_extra
]) ])

View file

@ -14,6 +14,7 @@
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
| Stefan Röhrich <sr@linux.de> | | Stefan Röhrich <sr@linux.de> |
| Michael Wallner <mike@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -24,38 +25,49 @@
#include <zlib.h> #include <zlib.h>
#define PHP_ZLIB_ENCODING_RAW -0xf
#define PHP_ZLIB_ENCODING_GZIP 0x1f
#define PHP_ZLIB_ENCODING_DEFLATE 0x0f
#define PHP_ZLIB_ENCODING_ANY 0x2f
#define PHP_ZLIB_OUTPUT_HANDLER_NAME "zlib output compression"
#define PHP_ZLIB_BUFFER_SIZE_GUESS(in_len) (((size_t) ((double) in_len * (double) 1.015)) + 10 + 8 + 4 + 1)
ZEND_BEGIN_MODULE_GLOBALS(zlib) ZEND_BEGIN_MODULE_GLOBALS(zlib)
/* variables for transparent gzip encoding */ /* variables for transparent gzip encoding */
int compression_coding; int compression_coding;
z_stream stream;
uLong crc;
int ob_gzhandler_status;
long output_compression; long output_compression;
long output_compression_level; long output_compression_level;
char *output_handler; char *output_handler;
ZEND_END_MODULE_GLOBALS(zlib) ZEND_END_MODULE_GLOBALS(zlib);
PHPAPI ZEND_EXTERN_MODULE_GLOBALS(zlib) typedef struct _php_zlib_buffer {
char *data;
char *aptr;
size_t used;
size_t free;
size_t size;
} php_zlib_buffer;
typedef struct _php_zlib_context {
z_stream Z;
php_zlib_buffer buffer;
} php_zlib_context;
php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
extern php_stream_ops php_stream_gzio_ops;
extern php_stream_wrapper php_stream_gzip_wrapper;
extern php_stream_filter_factory php_zlib_filter_factory; extern php_stream_filter_factory php_zlib_filter_factory;
extern zend_module_entry php_zlib_module_entry; extern zend_module_entry php_zlib_module_entry;
#define zlib_module_ptr &php_zlib_module_entry #define zlib_module_ptr &php_zlib_module_entry
int php_ob_gzhandler_check(TSRMLS_D);
php_stream *php_stream_gzopen(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
extern php_stream_wrapper php_stream_gzip_wrapper;
#ifdef ZTS
#define ZLIBG(v) TSRMG(zlib_globals_id, zend_zlib_globals *, v)
#else
#define ZLIBG(v) (zlib_globals.v)
#endif
#define phpext_zlib_ptr zlib_module_ptr #define phpext_zlib_ptr zlib_module_ptr
#define CODING_GZIP 1 #ifdef ZTS
#define CODING_DEFLATE 2 # define ZLIBG(v) TSRMG(zlib_globals_id, zend_zlib_globals *, v)
#else
# define ZLIBG(v) (zlib_globals.v)
#endif
#endif /* PHP_ZLIB_H */ #endif /* PHP_ZLIB_H */

View file

@ -48,6 +48,8 @@ string(%d) "%a"
Warning: gzinflate() expects at least 1 parameter, 0 given in %s on line %d Warning: gzinflate() expects at least 1 parameter, 0 given in %s on line %d
NULL NULL
Warning: gzinflate(): data error in %s on line %d
bool(false) bool(false)
Warning: gzinflate(): data error in %s on line %d Warning: gzinflate(): data error in %s on line %d

View file

@ -11,8 +11,8 @@ var_dump(gzencode("", -10));
var_dump(gzencode("", 100)); var_dump(gzencode("", 100));
var_dump(gzencode("", 1, 100)); var_dump(gzencode("", 1, 100));
var_dump(gzencode("", -1, 1)); var_dump(gzencode("", -1, ZLIB_ENCODING_GZIP));
var_dump(gzencode("", 9, 2)); var_dump(gzencode("", 9, ZLIB_ENCODING_DEFLATE));
$string = "Light of my sun $string = "Light of my sun
Light in this temple Light in this temple
@ -21,8 +21,8 @@ Lies in the darkness";
var_dump(gzencode($string, 9, 3)); var_dump(gzencode($string, 9, 3));
var_dump(gzencode($string, -1, 1)); var_dump(gzencode($string, -1, ZLIB_ENCODING_GZIP));
var_dump(gzencode($string, 9, 2)); var_dump(gzencode($string, 9, ZLIB_ENCODING_DEFLATE));
echo "Done\n"; echo "Done\n";
?> ?>
@ -33,18 +33,18 @@ NULL
Warning: gzencode() expects at most 3 parameters, 4 given in %s on line %d Warning: gzencode() expects at most 3 parameters, 4 given in %s on line %d
NULL NULL
Warning: gzencode(): compression level(-10) must be within -1..9 in %s on line %d Warning: gzencode(): compression level (-10) must be within -1..9 in %s on line %d
bool(false) bool(false)
Warning: gzencode(): compression level(100) must be within -1..9 in %s on line %d Warning: gzencode(): compression level (100) must be within -1..9 in %s on line %d
bool(false) bool(false)
Warning: gzencode(): encoding mode must be FORCE_GZIP or FORCE_DEFLATE in %s on line %d Warning: gzencode(): encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE in %s on line %d
bool(false) bool(false)
string(%d) "%s" string(%d) "%s"
string(%d) "%s" string(%d) "%s"
Warning: gzencode(): encoding mode must be FORCE_GZIP or FORCE_DEFLATE in %s on line %d Warning: gzencode(): encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE in %s on line %d
bool(false) bool(false)
string(%d) "%s" string(%d) "%s"
string(%d) "%s" string(%d) "%s"

View file

@ -8,7 +8,7 @@ if (!extension_loaded("zlib")) {
?> ?>
--FILE-- --FILE--
<?php <?php
/* Prototype : string gzcompress(string data [, int level]) /* Prototype : string gzcompress(string data [, int level, [int encoding]])
* Description: Gzip-compress a string * Description: Gzip-compress a string
* Source code: ext/zlib/zlib.c * Source code: ext/zlib/zlib.c
* Alias to functions: * Alias to functions:
@ -63,7 +63,7 @@ int(0)
string(32) "c2e070f4320d1f674965eaab95b53d9c" string(32) "c2e070f4320d1f674965eaab95b53d9c"
int(0) int(0)
-- Compression level 2 -- -- Compression level 2 --
string(32) "400a53d19ca337727f8cd362f5cd3ee0" string(32) "36922f486410d08209d0d0d21b26030e"
int(0) int(0)
-- Compression level 3 -- -- Compression level 3 --
string(32) "a441a2f5169bb303cd45b860a5a9dbf9" string(32) "a441a2f5169bb303cd45b860a5a9dbf9"
@ -122,4 +122,4 @@ int(0)
-- Testing with no specified compression level -- -- Testing with no specified compression level --
string(70) "789c735428ce4dccc951282e29cacc4b5728c95748cecf2d284a2d2ee6020087a509cb" string(70) "789c735428ce4dccc951282e29cacc4b5728c95748cecf2d284a2d2ee6020087a509cb"
===Done=== ===Done===

View file

@ -8,7 +8,7 @@ if (!extension_loaded("zlib")) {
?> ?>
--FILE-- --FILE--
<?php <?php
/* Prototype : string gzcompress(string data [, int level]) /* Prototype : string gzcompress(string data [, int level, [int encoding]])
* Description: Gzip-compress a string * Description: Gzip-compress a string
* Source code: ext/zlib/zlib.c * Source code: ext/zlib/zlib.c
* Alias to functions: * Alias to functions:
@ -28,26 +28,30 @@ var_dump( gzcompress() );
echo "\n-- Testing gzcompress() function with more than expected no. of arguments --\n"; echo "\n-- Testing gzcompress() function with more than expected no. of arguments --\n";
$data = 'string_val'; $data = 'string_val';
$level = 2; $level = 2;
$encoding = ZLIB_ENCODING_RAW;
$extra_arg = 10; $extra_arg = 10;
var_dump( gzcompress($data, $level, $extra_arg) ); var_dump( gzcompress($data, $level, $encoding, $extra_arg) );
echo "\n-- Testing with incorrect compression level --\n"; echo "\n-- Testing with incorrect compression level --\n";
$bad_level = 99; $bad_level = 99;
var_dump(gzcompress($data, $bad_level)); var_dump(gzcompress($data, $bad_level));
echo "\n-- Testing with invalid encoding --\n";
$data = 'string_val';
$encoding = 99;
var_dump(gzcompress($data, $level, $encoding));
echo "\n-- Testing with incorrect parameters --\n";
class Tester { class Tester {
function Hello() { function Hello() {
echo "Hello\n"; echo "Hello\n";
} }
} }
echo "\n-- Testing with incorrect parameters --\n";
$testclass = new Tester(); $testclass = new Tester();
var_dump(gzcompress($testclass)); var_dump(gzcompress($testclass));
var_dump(gzcompress($data, $testclass));
?> ?>
===Done=== ===Done===
--EXPECTF-- --EXPECTF--
@ -60,7 +64,7 @@ NULL
-- Testing gzcompress() function with more than expected no. of arguments -- -- Testing gzcompress() function with more than expected no. of arguments --
Warning: gzcompress() expects at most 2 parameters, 3 given in %s on line %d Warning: gzcompress() expects at most 3 parameters, 4 given in %s on line %d
NULL NULL
-- Testing with incorrect compression level -- -- Testing with incorrect compression level --
@ -68,11 +72,13 @@ NULL
Warning: gzcompress(): compression level (99) must be within -1..9 in %s on line %d Warning: gzcompress(): compression level (99) must be within -1..9 in %s on line %d
bool(false) bool(false)
-- Testing with invalid encoding --
Warning: gzcompress(): encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE in %s on line %d
bool(false)
-- Testing with incorrect parameters -- -- Testing with incorrect parameters --
Warning: gzcompress() expects parameter 1 to be string, object given in %s on line %d Warning: gzcompress() expects parameter 1 to be string, object given in %s on line %d
NULL NULL
===Done===
Warning: gzcompress() expects parameter 2 to be long, object given in %s on line %d
NULL
===Done===

View file

@ -8,7 +8,7 @@ if (!extension_loaded("zlib")) {
?> ?>
--FILE-- --FILE--
<?php <?php
/* Prototype : string gzcompress(string data [, int level]) /* Prototype : string gzcompress(string data [, int level, [int encoding]])
* Description: Gzip-compress a string * Description: Gzip-compress a string
* Source code: ext/zlib/zlib.c * Source code: ext/zlib/zlib.c
* Alias to functions: * Alias to functions:
@ -18,8 +18,6 @@ include(dirname(__FILE__) . '/data.inc');
echo "*** Testing gzcompress() : variation ***\n"; echo "*** Testing gzcompress() : variation ***\n";
echo "\n-- Testing multiple compression --\n"; echo "\n-- Testing multiple compression --\n";
$output = gzcompress($data); $output = gzcompress($data);
var_dump( md5($output)); var_dump( md5($output));
@ -33,4 +31,4 @@ var_dump(md5(gzcompress($output)));
-- Testing multiple compression -- -- Testing multiple compression --
string(32) "764809aef15bb34cb73ad49ecb600d99" string(32) "764809aef15bb34cb73ad49ecb600d99"
string(32) "eba942bc2061f23ea8688cc5101872a4" string(32) "eba942bc2061f23ea8688cc5101872a4"
===Done=== ===Done===

View file

@ -8,7 +8,7 @@ if (!extension_loaded("zlib")) {
?> ?>
--FILE-- --FILE--
<?php <?php
/* Prototype : proto string gzdeflate(string data [, int level]) /* Prototype : string gzdeflate(string data [, int level, [int encoding]])
* Description: Gzip-compress a string * Description: Gzip-compress a string
* Source code: ext/zlib/zlib.c * Source code: ext/zlib/zlib.c
* Alias to functions: * Alias to functions:

View file

@ -8,7 +8,7 @@ if (!extension_loaded("zlib")) {
?> ?>
--FILE-- --FILE--
<?php <?php
/* Prototype : string gzdeflate(string data [, int level]) /* Prototype : string gzdeflate(string data [, int level, [int encoding]])
* Description: Gzip-compress a string * Description: Gzip-compress a string
* Source code: ext/zlib/zlib.c * Source code: ext/zlib/zlib.c
* Alias to functions: * Alias to functions:
@ -28,13 +28,18 @@ var_dump( gzdeflate() );
echo "\n-- Testing gzdeflate() function with more than expected no. of arguments --\n"; echo "\n-- Testing gzdeflate() function with more than expected no. of arguments --\n";
$data = 'string_val'; $data = 'string_val';
$level = 2; $level = 2;
$encoding = ZLIB_ENCODING_RAW;
$extra_arg = 10; $extra_arg = 10;
var_dump( gzdeflate($data, $level, $extra_arg) ); var_dump( gzdeflate($data, $level, $encoding, $extra_arg) );
echo "\n-- Testing with incorrect compression level --\n"; echo "\n-- Testing with incorrect compression level --\n";
$bad_level = 99; $bad_level = 99;
var_dump(gzdeflate($data, $bad_level)); var_dump(gzdeflate($data, $bad_level));
echo "\n-- Testing with incorrect encoding --\n";
$bad_encoding = 99;
var_dump(gzdeflate($data, $level, $bad_encoding));
class Tester { class Tester {
function Hello() { function Hello() {
echo "Hello\n"; echo "Hello\n";
@ -58,7 +63,7 @@ NULL
-- Testing gzdeflate() function with more than expected no. of arguments -- -- Testing gzdeflate() function with more than expected no. of arguments --
Warning: gzdeflate() expects at most 2 parameters, 3 given in %s on line %d Warning: gzdeflate() expects at most 3 parameters, 4 given in %s on line %d
NULL NULL
-- Testing with incorrect compression level -- -- Testing with incorrect compression level --
@ -66,6 +71,11 @@ NULL
Warning: gzdeflate(): compression level (99) must be within -1..9 in %s on line %d Warning: gzdeflate(): compression level (99) must be within -1..9 in %s on line %d
bool(false) bool(false)
-- Testing with incorrect encoding --
Warning: gzdeflate(): encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE in %s on line %d
bool(false)
-- Testing with incorrect parameters -- -- Testing with incorrect parameters --
Warning: gzdeflate() expects parameter 1 to be string, object given in %s on line %d Warning: gzdeflate() expects parameter 1 to be string, object given in %s on line %d
@ -73,4 +83,4 @@ NULL
Warning: gzdeflate() expects parameter 2 to be long, object given in %s on line %d Warning: gzdeflate() expects parameter 2 to be long, object given in %s on line %d
NULL NULL
===Done=== ===Done===

View file

@ -51,6 +51,13 @@ for($i = -1; $i < 10; $i++) {
var_dump(md5($output)); var_dump(md5($output));
} }
// Calling gzencode() with mandatory arguments
echo "\n-- Testing with no specified compression level --\n";
var_dump(bin2hex(gzencode($smallstring)));
echo "\n-- Testing gzencode with mode specified --\n";
var_dump(bin2hex(gzencode($smallstring, -1, FORCE_GZIP)));
?> ?>
===Done=== ===Done===
--EXPECTF-- --EXPECTF--
@ -58,9 +65,9 @@ for($i = -1; $i < 10; $i++) {
-- Compression level -1 -- -- Compression level -1 --
string(32) "d9ede02415ce91d21e5a94274e2b9c42" string(32) "d9ede02415ce91d21e5a94274e2b9c42"
-- Compression level 0 -- -- Compression level 0 --
string(32) "67aaf60426bb2cbd86d7fe530cb12306" string(32) "bbf32d5508e5f1f4e6d42790489dae15"
-- Compression level 1 -- -- Compression level 1 --
string(32) "bce9c439cf767c1988ff4881b287d1ce" string(32) "0bfaaa7a5a57f8fb533074fca6c85eeb"
-- Compression level 2 -- -- Compression level 2 --
string(32) "7ddbfed63a76c42808722b66f1c133fc" string(32) "7ddbfed63a76c42808722b66f1c133fc"
-- Compression level 3 -- -- Compression level 3 --
@ -76,13 +83,13 @@ string(32) "d9ede02415ce91d21e5a94274e2b9c42"
-- Compression level 8 -- -- Compression level 8 --
string(32) "d9ede02415ce91d21e5a94274e2b9c42" string(32) "d9ede02415ce91d21e5a94274e2b9c42"
-- Compression level 9 -- -- Compression level 9 --
string(32) "d9ede02415ce91d21e5a94274e2b9c42" string(32) "0f220a09e9895bcb3a1308d2bc99cfdf"
-- Compression level -1 -- -- Compression level -1 --
string(32) "f77bd31e1e4dd11d12828fb661a08010" string(32) "f77bd31e1e4dd11d12828fb661a08010"
-- Compression level 0 -- -- Compression level 0 --
string(32) "36220d650930849b67e8e0622f9bf270" string(32) "9c5005db88490d6fe102ea2c233b2872"
-- Compression level 1 -- -- Compression level 1 --
string(32) "f77bd31e1e4dd11d12828fb661a08010" string(32) "d24ff7c4c20cef69b9c3abd603368db9"
-- Compression level 2 -- -- Compression level 2 --
string(32) "f77bd31e1e4dd11d12828fb661a08010" string(32) "f77bd31e1e4dd11d12828fb661a08010"
-- Compression level 3 -- -- Compression level 3 --
@ -98,5 +105,11 @@ string(32) "f77bd31e1e4dd11d12828fb661a08010"
-- Compression level 8 -- -- Compression level 8 --
string(32) "f77bd31e1e4dd11d12828fb661a08010" string(32) "f77bd31e1e4dd11d12828fb661a08010"
-- Compression level 9 -- -- Compression level 9 --
string(32) "f77bd31e1e4dd11d12828fb661a08010" string(32) "8849e9a1543c04b3f882b5ce20839ed2"
===Done===
-- Testing with no specified compression level --
string(94) "1f8b08000000000000%c%c735428ce4dccc951282e29cacc4b5728c95748cecf2d284a2d2ee60200edc4e40b1b000000"
-- Testing gzencode with mode specified --
string(94) "1f8b08000000000000%c%c735428ce4dccc951282e29cacc4b5728c95748cecf2d284a2d2ee60200edc4e40b1b000000"
===Done===

View file

@ -71,12 +71,12 @@ NULL
-- Testing with incorrect compression level -- -- Testing with incorrect compression level --
Warning: gzencode(): compression level(99) must be within -1..9 in %s on line %d Warning: gzencode(): compression level (99) must be within -1..9 in %s on line %d
bool(false) bool(false)
-- Testing with incorrect encoding_mode -- -- Testing with incorrect encoding_mode --
Warning: gzencode(): encoding mode must be FORCE_GZIP or FORCE_DEFLATE in %s on line %d Warning: gzencode(): encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE in %s on line %d
bool(false) bool(false)
-- Testing with incorrect parameters -- -- Testing with incorrect parameters --
@ -87,7 +87,7 @@ NULL
Warning: gzencode() expects parameter 2 to be long, object given in %s on line %d Warning: gzencode() expects parameter 2 to be long, object given in %s on line %d
NULL NULL
Warning: gzencode(): encoding mode must be FORCE_GZIP or FORCE_DEFLATE in %s on line %d Warning: gzencode(): encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE in %s on line %d
bool(false) bool(false)
Warning: gzencode() expects parameter 3 to be long, object given in %s on line %d Warning: gzencode() expects parameter 3 to be long, object given in %s on line %d
@ -95,4 +95,4 @@ NULL
Warning: gzencode() expects parameter 2 to be long, string given in %s on line %d Warning: gzencode() expects parameter 2 to be long, string given in %s on line %d
NULL NULL
===Done=== ===Done===

View file

@ -3,6 +3,10 @@ Test gzencode() function : variation
--SKIPIF-- --SKIPIF--
<?php <?php
if( substr(PHP_OS, 0, 3) == "WIN" ) {
die("skip.. Do not run on Windows");
}
if (!extension_loaded("zlib")) { if (!extension_loaded("zlib")) {
print "skip - ZLIB extension not loaded"; print "skip - ZLIB extension not loaded";
} }
@ -30,4 +34,4 @@ var_dump(bin2hex(gzencode($output)));
-- Testing multiple compression -- -- Testing multiple compression --
string(3658) "1f8b0800000000000003010e07f1f81f8b08000000000000036d574d6fe4c80dbdeb57d4ad2f3dfe01eb83e1ec22980e309b4562c067b64449159754dafab0b6e7d7e73d96da1e4c72184c4b2ab2c8f7c847fa25baabba98dc1a8b2b7c38bb324b713ee37f757f56cdc5c7f5b17b9d152f923b157c5ae335e0b75fedd0e2d781c6b98ea3a6ee05affe1dfc3a6527f8f09c52dcb38ba38bb5249934d6ecfe1e53a9ab76ff4c342cf2a64ed2028349fc9a8b139755685352acb82b9fbb67f8bade5cdcb698e1fcec94b7ceba3cb897e806cfc8114350dd1ebbdfa35b62d2478b0056d23ed809b9b95d696d91ce2aa97c911e3fa539c43f84c887554a4d125c9e63ff96711cc08c0866263cb37a0bbe2122ae8f6baecb2284abfb4ddf916db8354cddeef37c1afe5fa02fc7afb3db34f5b3acbdf2eb905490d8f38d7468d253a323d5ebb903760d7944d3b2024e834a99ddce77669bdd823cfbb8e899d4ad4c799677452e6029e80023a03b2374005590641f7d3877df2ad09f3c0e82a54d6a5644fd63049a37ed4bc362016fd9f51264f1e5c630727421ae930b7ed416e93e47b7c71a400390361ffbecb7561bb98f69b5da289e91becc27f08b3b724cb8704f9144d366431d0cb870c56b205deaa2e17636063761a911039fb7e4bf9f06c4f0aecd2ec80e8b41831ca7515e31286166458ea3ef71f2ce7cde2ae269c96d60525724a9c9170b713ed5750758f3cd2a361fc8b288fc92358ce884692e8ea0fe59bd969a0da2eed5831b715749eaae7178f3ebd30fb88c92105f367cce2c882955dc6bf8eca0d5d57540b3092894743ba0fd5b2dad021836191f1afc0bba14dde1642cb0b1aa6879c38907dcefa0720082b801bec61417469219175267dfa047df35b0bd1332001c28cdfafd3bcabe91e74368cdd8d8478e494c190e7ee90c67f2bde288e68ab6b15e883c995be4f8feb6c6dda4278e4f38578ddbdc7be36788daf0c3cb1d1819c73822f7000a0d1813fa94153b572315e51343b536bc64977dff163cebfd8418773261f524017e251fccc60ae29a5770ae097594d52e9c1229d87ce967a36401c46b69945afb249d101c9d420ffa9a123e232c20e76467d5d169202a2dd4c582949e013e745df7958d4b0cc4fd4377a737cd4feea7974070000f314d423e0634cb9a618fdf5dc64fd422181fd59c9230c9f6f9d18dc8fc23e9cccbc7188733b04aa57de83ebea0be3633cff5fa1ff83269be7f44f5a8d84550cc703255fd345dd402034d0b3e11a73ec6e3d4a77f4f685b614329f1b3132ae7af33d02e1e55e291fa6574b758d1f0200e7423dbc852211818043a7c9ce80aa9d59fce0401959f5ea2cf71fde90824f8c9192dbe9d329db143794675ddcf257dd7755273b67340414e3ccad12e3f661f8aad9cf9957dc1275d10a51d3934fa81e68dc6768fb8ee23e373936c8e13feab8b0f50d227f7af76f561fb0950f3d099bbc316c3892a42fb36806d8660e800fa4f43fd4b962d2097d71933a54b77ff948677848eb17bb3a88b621682cfb3bbb49cf42fed6b3944124ad8358ca688aa44dd5f2144c7c9ab16f25b9aca9654ef357ec9ad55c40d324d6cc3d9e3920b863c231d31a95d937fb5520f9c816c79b7dcecc593fb9593cc05a51ebb1eeddd5b49eb437769738d0f64adc579d372b8b7f7c0208487ee3915ebf5766e148ebd77cf4e01f3ec285047011e55838968b6494d517fe29224777b24dd3ddf933101695b102e87db805eef291b74dcfd91628fb2a53f93dbd2968ef2e598746c9204f89fba1f0246fc671610a0591806e46a1346f77c40d910a47c5e20ffb23f003c04b648327a4ed98032c1965bd35bb0044f5344248f56fdb99aa61d6451d68e33489a83bffbe6573541b2da5f64681ea12090f778b2075374778810f73965fa3626a9d41f4df2f83f7c34658cec921b5a9bde49dd5007ec882b02adc514f81aa85898b5cc98e1b137733c0a8789b7f5648d2d231b80bf74978f25d61ce08a8abd11801fd8f995e066676307192ff7641f1cc6e0dee68565b8b22ac3889cd067bf732754a6b270af1044c6a8776811a4f6d8bd0477a9f516064201b920b92d7cd4dc7eee13e6b3eb3528a82f9abb3f388ebe6a8f871393461b73816ec54c99d604174bc5a6801de13908f86aea6a7d0fea107d682bcf1ec348b83872e6b8a316ecd02eb8f8dc86a609bf59a2dd03f1dfa4079436d55e24617be1a2854d008b2b2b1705e2078a7f3946318df1c24f6bf70d4b456eca286ec2b585b28262cc048a098c3e2d5f325a92bb36f691afdc14c822da1b116c9c1c07bb362eb0a04b78834c812134230ebf2044ac2e3c0e3ad00f848dc5010f3bf917ec2fc700b7bf26dacea8440620e04f90f4d97d6dd77cfde8a05c7d3930f1e5811fb8ec5c70964dcc8187ec90e32fdd6b64eec7586413b7d55bed65c4cce39a9b6c15e70e9da94e53fc904e6286f01f5b5562c94211befbc23507e01b2a3865e2f45b5d7b591f290087a5605b82495b4e393f31aa5b37211ec40241a746d903c5eebf117a4d3ddb0d00007b64cbc70e070000" string(3658) "1f8b0800000000000003010e07f1f81f8b08000000000000036d574d6fe4c80dbdeb57d4ad2f3dfe01eb83e1ec22980e309b4562c067b64449159754dafab0b6e7d7e73d96da1e4c72184c4b2ab2c8f7c847fa25baabba98dc1a8b2b7c38bb324b713ee37f757f56cdc5c7f5b17b9d152f923b157c5ae335e0b75fedd0e2d781c6b98ea3a6ee05affe1dfc3a6527f8f09c52dcb38ba38bb5249934d6ecfe1e53a9ab76ff4c342cf2a64ed2028349fc9a8b139755685352acb82b9fbb67f8bade5cdcb698e1fcec94b7ceba3cb897e806cfc8114350dd1ebbdfa35b62d2478b0056d23ed809b9b95d696d91ce2aa97c911e3fa539c43f84c887554a4d125c9e63ff96711cc08c0866263cb37a0bbe2122ae8f6baecb2284abfb4ddf916db8354cddeef37c1afe5fa02fc7afb3db34f5b3acbdf2eb905490d8f38d7468d253a323d5ebb903760d7944d3b2024e834a99ddce77669bdd823cfbb8e899d4ad4c799677452e6029e80023a03b2374005590641f7d3877df2ad09f3c0e82a54d6a5644fd63049a37ed4bc362016fd9f51264f1e5c630727421ae930b7ed416e93e47b7c71a400390361ffbecb7561bb98f69b5da289e91becc27f08b3b724cb8704f9144d366431d0cb870c56b205deaa2e17636063761a911039fb7e4bf9f06c4f0aecd2ec80e8b41831ca7515e31286166458ea3ef71f2ce7cde2ae269c96d60525724a9c9170b713ed5750758f3cd2a361fc8b288fc92358ce884692e8ea0fe59bd969a0da2eed5831b715749eaae7178f3ebd30fb88c92105f367cce2c882955dc6bf8eca0d5d57540b3092894743ba0fd5b2dad021836191f1afc0bba14dde1642cb0b1aa6879c38907dcefa0720082b801bec61417469219175267dfa047df35b0bd1332001c28cdfafd3bcabe91e74368cdd8d8478e494c190e7ee90c67f2bde288e68ab6b15e883c995be4f8feb6c6dda4278e4f38578ddbdc7be36788daf0c3cb1d1819c73822f7000a0d1813fa94153b572315e51343b536bc64977dff163cebfd8418773261f524017e251fccc60ae29a5770ae097594d52e9c1229d87ce967a36401c46b69945afb249d101c9d420ffa9a123e232c20e76467d5d169202a2dd4c582949e013e745df7958d4b0cc4fd4377a737cd4feea7974070000f314d423e0634cb9a618fdf5dc64fd422181fd59c9230c9f6f9d18dc8fc23e9cccbc7188733b04aa57de83ebea0be3633cff5fa1ff83269be7f44f5a8d84550cc703255fd345dd402034d0b3e11a73ec6e3d4a77f4f685b614329f1b3132ae7af33d02e1e55e291fa6574b758d1f0200e7423dbc852211818043a7c9ce80aa9d59fce0401959f5ea2cf71fde90824f8c9192dbe9d329db143794675ddcf257dd7755273b67340414e3ccad12e3f661f8aad9cf9957dc1275d10a51d3934fa81e68dc6768fb8ee23e373936c8e13feab8b0f50d227f7af76f561fb0950f3d099bbc316c3892a42fb36806d8660e800fa4f43fd4b962d2097d71933a54b77ff948677848eb17bb3a88b621682cfb3bbb49cf42fed6b3944124ad8358ca688aa44dd5f2144c7c9ab16f25b9aca9654ef357ec9ad55c40d324d6cc3d9e3920b863c231d31a95d937fb5520f9c816c79b7dcecc593fb9593cc05a51ebb1eeddd5b49eb437769738d0f64adc579d372b8b7f7c0208487ee3915ebf5766e148ebd77cf4e01f3ec285047011e55838968b6494d517fe29224777b24dd3ddf933101695b102e87db805eef291b74dcfd91628fb2a53f93dbd2968ef2e598746c9204f89fba1f0246fc671610a0591806e46a1346f77c40d910a47c5e20ffb23f003c04b648327a4ed98032c1965bd35bb0044f5344248f56fdb99aa61d6451d68e33489a83bffbe6573541b2da5f64681ea12090f778b2075374778810f73965fa3626a9d41f4df2f83f7c34658cec921b5a9bde49dd5007ec882b02adc514f81aa85898b5cc98e1b137733c0a8789b7f5648d2d231b80bf74978f25d61ce08a8abd11801fd8f995e066676307192ff7641f1cc6e0dee68565b8b22ac3889cd067bf732754a6b270af1044c6a8776811a4f6d8bd0477a9f516064201b920b92d7cd4dc7eee13e6b3eb3528a82f9abb3f388ebe6a8f871393461b73816ec54c99d604174bc5a6801de13908f86aea6a7d0fea107d682bcf1ec348b83872e6b8a316ecd02eb8f8dc86a609bf59a2dd03f1dfa4079436d55e24617be1a2854d008b2b2b1705e2078a7f3946318df1c24f6bf70d4b456eca286ec2b585b28262cc048a098c3e2d5f325a92bb36f691afdc14c822da1b116c9c1c07bb362eb0a04b78834c812134230ebf2044ac2e3c0e3ad00f848dc5010f3bf917ec2fc700b7bf26dacea8440620e04f90f4d97d6dd77cfde8a05c7d3930f1e5811fb8ec5c70964dcc8187ec90e32fdd6b64eec7586413b7d55bed65c4cce39a9b6c15e70e9da94e53fc904e6286f01f5b5562c94211befbc23507e01b2a3865e2f45b5d7b591f290087a5605b82495b4e393f31aa5b37211ec40241a746d903c5eebf117a4d3ddb0d00007b64cbc70e070000"
===Done=== ===Done===

View file

@ -0,0 +1,42 @@
--TEST--
Test gzencode() function : variation - verify header contents with all encoding modes
--XFAIL--
Test will fail until bug #47178 resolved; missing gzip headers whne FORCE_DEFLATE specified
--SKIPIF--
<?php
if( substr(PHP_OS, 0, 3) != "WIN" ) {
die("skip.. only for Windows");
}
if (!extension_loaded("zlib")) {
print "skip - ZLIB extension not loaded";
}
?>
--FILE--
<?php
/* Prototype : string gzencode ( string $data [, int $level [, int $encoding_mode ]] )
* Description: Gzip-compress a string
* Source code: ext/zlib/zlib.c
* Alias to functions:
*/
echo "*** Testing gzencode() : variation ***\n";
$data = "A small string to encode\n";
echo "\n-- Testing with each encoding_mode --\n";
var_dump(bin2hex(gzencode($data, -1)));
var_dump(bin2hex(gzencode($data, -1, FORCE_GZIP)));
var_dump(bin2hex(gzencode($data, -1, FORCE_DEFLATE)));
?>
===DONE===
--EXPECTF--
*** Testing gzencode() : variation ***
-- Testing with each encoding_mode --
string(90) "1f8b080000000000000b735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200d7739de519000000"
string(90) "1f8b080000000000000b735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200d7739de519000000"
string(86) "1f8b080000000000000b789c735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200735808cd"
===DONE===

View file

@ -1,8 +1,14 @@
--TEST-- --TEST--
Test gzencode() function : variation - verify header contents with all encoding modes Test gzencode() function : variation - verify header contents with all encoding modes
--XFAIL--
Test will fail until bug #47178 resolved; missing gzip headers whne FORCE_DEFLATE specified
--SKIPIF-- --SKIPIF--
<?php <?php
if( substr(PHP_OS, 0, 3) == "WIN" ) {
die("skip.. Do not run on Windows");
}
if (!extension_loaded("zlib")) { if (!extension_loaded("zlib")) {
print "skip - ZLIB extension not loaded"; print "skip - ZLIB extension not loaded";
} }
@ -33,4 +39,4 @@ var_dump(bin2hex(gzencode($data, -1, FORCE_DEFLATE)));
string(90) "1f8b0800000000000003735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200d7739de519000000" string(90) "1f8b0800000000000003735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200d7739de519000000"
string(90) "1f8b0800000000000003735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200d7739de519000000" string(90) "1f8b0800000000000003735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200d7739de519000000"
string(86) "1f8b0800000000000003789c735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200735808cd" string(86) "1f8b0800000000000003789c735428ce4dccc951282e29cacc4b5728c95748cd4bce4f49e50200735808cd"
===DONE=== ===DONE===

View file

@ -5,8 +5,8 @@ Bug #42663 (gzinflate() try to allocate all memory with truncated $data)
--FILE-- --FILE--
<?php <?php
// build a predictable string // build a predictable string
$string = b''; $string = '';
for($i=0; $i<30000; ++$i) $string .= (binary)$i . b' '; for($i=0; $i<30000; ++$i) $string .= $i . ' ';
var_dump(strlen($string)); var_dump(strlen($string));
// deflate string // deflate string
$deflated = gzdeflate($string,9); $deflated = gzdeflate($string,9);
@ -15,9 +15,12 @@ var_dump(strlen($deflated));
$truncated = substr($deflated, 0, 65535); $truncated = substr($deflated, 0, 65535);
var_dump(strlen($truncated)); var_dump(strlen($truncated));
// inflate $truncated string (check if it will not eat all memory) // inflate $truncated string (check if it will not eat all memory)
gzinflate($truncated); var_dump(gzinflate($truncated));
?> ?>
--EXPECT-- --EXPECTF--
int(168890) int(168890)
int(66743) int(66743)
int(65535) int(65535)
Warning: gzinflate(): data error in %s on line %d
bool(false)

View file

@ -4,7 +4,7 @@ gzinflate() and $length argument
<?php if (!extension_loaded("zlib")) print "skip"; ?> <?php if (!extension_loaded("zlib")) print "skip"; ?>
--FILE-- --FILE--
<?php <?php
$original = b'aaaaaaaaaaaaaaa'; $original = 'aaaaaaaaaaaaaaa';
$packed=gzdeflate($original); $packed=gzdeflate($original);
echo strlen($packed)." ".strlen($original)."\n"; echo strlen($packed)." ".strlen($original)."\n";
$unpacked=gzinflate($packed, strlen($original)); $unpacked=gzinflate($packed, strlen($original));

View file

@ -5,7 +5,7 @@ gzopen(), gzread(), gzwrite()
if (!extension_loaded("zlib")) print "skip"; ?> if (!extension_loaded("zlib")) print "skip"; ?>
--FILE-- --FILE--
<?php <?php
$original = str_repeat("hallo php",4096); $original = str_repeat(b"hallo php",4096);
$filename = tempnam("/tmp", "phpt"); $filename = tempnam("/tmp", "phpt");
$fp = gzopen($filename, "wb"); $fp = gzopen($filename, "wb");
@ -15,7 +15,12 @@ var_dump(gztell($fp));
fclose($fp); fclose($fp);
$fp = gzopen($filename, "rb"); $fp = gzopen($filename, "rb");
$data = gzread($fp, strlen($original));
$data = '';
while ($buf = gzread($fp, 8092)) {
$data .= $buf;
}
if ($data == $original) { if ($data == $original) {
echo "Strings are equal\n"; echo "Strings are equal\n";
} else { } else {

View file

@ -5,7 +5,7 @@ gzopen(), gzread(), gzwrite() for non-compressed data
if (!extension_loaded("zlib")) print "skip"; ?> if (!extension_loaded("zlib")) print "skip"; ?>
--FILE-- --FILE--
<?php <?php
$original = str_repeat("hallo php",4096); $original = str_repeat(b"hallo php",4096);
$filename = tempnam("/tmp", "phpt"); $filename = tempnam("/tmp", "phpt");
$fp = fopen($filename, "wb"); $fp = fopen($filename, "wb");
@ -15,7 +15,12 @@ var_dump(ftell($fp));
fclose($fp); fclose($fp);
$fp = gzopen($filename, "rb"); $fp = gzopen($filename, "rb");
$data = gzread($fp, strlen($original));
$data = '';
while ($buf = gzread($fp, 8192)) {
$data .= $buf;
}
if ($data == $original) { if ($data == $original) {
echo "Strings are equal\n"; echo "Strings are equal\n";
} else { } else {
@ -24,7 +29,11 @@ if ($data == $original) {
} }
gzseek($fp, strlen($original) / 2); gzseek($fp, strlen($original) / 2);
$data = gzread($fp, strlen($original));
$data = '';
while ($buf = gzread($fp, 8192)) {
$data .= $buf;
}
var_dump(strlen($data)); var_dump(strlen($data));
if ($data == substr($original, strlen($original) / 2)) { if ($data == substr($original, strlen($original) / 2)) {

View file

@ -14,8 +14,6 @@ if (!extension_loaded("zlib")) {
* Alias to functions: * Alias to functions:
*/ */
echo "*** Testing gzuncompress() : error conditions ***\n"; echo "*** Testing gzuncompress() : error conditions ***\n";
// Zero arguments // Zero arguments
@ -29,14 +27,12 @@ $length = 10;
$extra_arg = 10; $extra_arg = 10;
var_dump( gzuncompress($data, $length, $extra_arg) ); var_dump( gzuncompress($data, $length, $extra_arg) );
echo "\n-- Testing with a buffer that is too small --\n"; echo "\n-- Testing with a buffer that is too small --\n";
$short_len = strlen($data) - 1; $short_len = strlen($data) - 1;
$compressed = gzcompress($data); $compressed = gzcompress($data);
var_dump(gzuncompress($compressed, $short_len)); var_dump(gzuncompress($compressed, $short_len));
echo "\n-- Testing with incorrect arguments --\n"; echo "\n-- Testing with incorrect arguments --\n";
var_dump(gzuncompress(123)); var_dump(gzuncompress(123));
@ -68,7 +64,7 @@ NULL
-- Testing with a buffer that is too small -- -- Testing with a buffer that is too small --
Warning: gzuncompress(): buffer error in %s on line %d Warning: gzuncompress(): insufficient memory in %s on line %d
bool(false) bool(false)
-- Testing with incorrect arguments -- -- Testing with incorrect arguments --
@ -81,4 +77,4 @@ NULL
Warning: gzuncompress() expects parameter 2 to be long, string given in %s on line %d Warning: gzuncompress() expects parameter 2 to be long, string given in %s on line %d
NULL NULL
===DONE=== ===DONE===

View file

@ -11,7 +11,7 @@ if (!extension_loaded("zlib")) {
$filename = dirname(__FILE__)."/004.txt.gz"; $filename = dirname(__FILE__)."/004.txt.gz";
$h = gzopen($filename, 'r'); $h = gzopen($filename, 'r');
$str = "Here is the string to be written. "; $str = b"Here is the string to be written. ";
$length = 10; $length = 10;
var_dump(gzwrite( $h, $str ) ); var_dump(gzwrite( $h, $str ) );
var_dump(gzread($h, 10)); var_dump(gzread($h, 10));

View file

@ -0,0 +1,20 @@
--TEST--
zlib.output_compression
--SKIPIF--
<?php
if (!extension_loaded("zlib")) die("skip need ext/zlib");
if (false === stristr(PHP_SAPI, "cgi")) die("skip need sapi/cgi");
?>
--GET--
a=b
--INI--
zlib.output_compression=1
--ENV--
HTTP_ACCEPT_ENCODING=gzip
--FILE--
<?php
echo "hi\n";
?>
--EXPECTF--
%s

View file

@ -0,0 +1,18 @@
--TEST--
zlib.output_compression
--SKIPIF--
<?php
if (!extension_loaded("zlib")) die("skip need ext/zlib");
?>
--INI--
zlib.output_compression=1
--ENV--
HTTP_ACCEPT_ENCODING=gzip
--FILE--
<?php
ini_set("zlib.output_compression", 0);
echo "hi\n";
?>
--EXPECTF--
hi

View file

@ -0,0 +1,25 @@
--TEST--
zlib.output_compression
--SKIPIF--
<?php
if (!extension_loaded("zlib")) die("skip need ext/zlib");
if (false === stristr(PHP_SAPI, "cgi")) die("skip need sapi/cgi");
?>
--INI--
zlib.output_compression=0
--ENV--
HTTP_ACCEPT_ENCODING=gzip
--POST--
dummy=42
--FILE--
<?php
ini_set("zlib.output_compression", 1);
echo "hi\n";
?>
--EXPECTF--
%s
Content-Encoding: gzip
Vary: Accept-Encoding
%s
%s

View file

@ -0,0 +1,25 @@
--TEST--
ob_gzhandler
--SKIPIF--
<?php
if (!extension_loaded("zlib")) die("skip need ext/zlib");
if (false === stristr(PHP_SAPI, "cgi")) die("skip need sapi/cgi");
?>
--INI--
zlib.output_compression=0
--ENV--
HTTP_ACCEPT_ENCODING=gzip
--POST--
dummy=42
--FILE--
<?php
ob_start("ob_gzhandler");
echo "hi\n";
?>
--EXPECTF--
%s
Content-Encoding: gzip
Vary: Accept-Encoding
%s
%s

View file

@ -0,0 +1,21 @@
--TEST--
ob_gzhandler
--SKIPIF--
<?php
if (!extension_loaded("zlib")) die("skip need ext/zlib");
if (false === stristr(PHP_SAPI, "cgi")) die("skip need sapi/cgi");
?>
--INI--
zlib.output_compression=0
--ENV--
HTTP_ACCEPT_ENCODING=gzip
--POST--
dummy=42
--FILE--
<?php
ob_start("ob_gzhandler");
ini_set("zlib.output_compression", 0);
echo "hi\n";
?>
--EXPECTF--
%shi

View file

@ -41,4 +41,4 @@ NULL
Warning: readgzfile() expects parameter 2 to be long, string given in %s on line %d Warning: readgzfile() expects parameter 2 to be long, string given in %s on line %d
NULL NULL
===DONE=== ===DONE===

View file

@ -26,9 +26,18 @@ foreach ( $variation as $var ) {
?> ?>
===DONE=== ===DONE===
--EXPECTF-- --EXPECTF--
Warning: readgzfile(10.5): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(-10.5): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(123456789000): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(-123456789000): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(0.5): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
===DONE=== ===DONE===

View file

@ -25,8 +25,15 @@ foreach ( $variation as $var ) {
?> ?>
===DONE=== ===DONE===
--EXPECTF-- --EXPECTF--
Warning: readgzfile(0): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(1): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(12345): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(-2345): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
===DONE=== ===DONE===

View file

@ -43,6 +43,7 @@ foreach ( $variation as $var ) {
} }
?> ?>
--EXPECTF-- --EXPECTF--
Error: 2 - readgzfile(Class A object): failed to open stream: No such file or directory, %s(%d)
bool(false) bool(false)
Error: 2 - readgzfile() expects parameter 1 to be string, object given, %s(%d) Error: 2 - readgzfile() expects parameter 1 to be string, object given, %s(%d)
NULL NULL

View file

@ -29,8 +29,15 @@ foreach ( $variation_array as $var ) {
?> ?>
===DONE=== ===DONE===
--EXPECTF-- --EXPECTF--
Warning: readgzfile(string): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(string): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(sTrInG): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
Warning: readgzfile(hello world): failed to open stream: No such file or directory in %s on line %d
bool(false) bool(false)
===DONE=== ===DONE===

View file

@ -6,7 +6,7 @@ zlib.inflate of gzip-encoded stream
<?php /* $Id$ */ <?php /* $Id$ */
$a = gzopen(dirname(__FILE__) . '/test.txt.gz', 'w'); $a = gzopen(dirname(__FILE__) . '/test.txt.gz', 'w');
fwrite($a, "This is quite the thing ain't it\n"); fwrite($a, b"This is quite the thing ain't it\n");
fclose($a); fclose($a);
$fp = fopen(dirname(__FILE__) . '/test.txt.gz', 'r'); $fp = fopen(dirname(__FILE__) . '/test.txt.gz', 'r');
@ -38,4 +38,4 @@ fclose($fp);
2 2
This is quite the thing ain't it This is quite the thing ain't it
3 3
This is quite the thing ain't it This is quite the thing ain't it

File diff suppressed because it is too large Load diff

View file

@ -80,8 +80,11 @@ static php_stream_filter_status_t php_zlib_inflate_filter(
while (buckets_in->head) { while (buckets_in->head) {
size_t bin = 0, desired; size_t bin = 0, desired;
bucket = buckets_in->head;
bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC); bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC);
while (bin < bucket->buflen) {
while (bin < (unsigned int) bucket->buflen) {
if (data->finished) { if (data->finished) {
consumed += bucket->buflen; consumed += bucket->buflen;
@ -107,7 +110,6 @@ static php_stream_filter_status_t php_zlib_inflate_filter(
desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */ desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */
data->strm.next_in = data->inbuf; data->strm.next_in = data->inbuf;
data->strm.avail_in = 0; data->strm.avail_in = 0;
consumed += desired;
bin += desired; bin += desired;
if (data->strm.avail_out < data->outbuf_len) { if (data->strm.avail_out < data->outbuf_len) {
@ -123,7 +125,9 @@ static php_stream_filter_status_t php_zlib_inflate_filter(
php_stream_bucket_delref(bucket TSRMLS_CC); php_stream_bucket_delref(bucket TSRMLS_CC);
return PSFS_PASS_ON; return PSFS_PASS_ON;
} }
} }
consumed += bucket->buflen;
php_stream_bucket_delref(bucket TSRMLS_CC); php_stream_bucket_delref(bucket TSRMLS_CC);
} }
@ -202,9 +206,11 @@ static php_stream_filter_status_t php_zlib_deflate_filter(
while (buckets_in->head) { while (buckets_in->head) {
size_t bin = 0, desired; size_t bin = 0, desired;
bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC); bucket = buckets_in->head;
while (bin < bucket->buflen) { bucket = php_stream_bucket_make_writeable(bucket TSRMLS_CC);
while (bin < (unsigned int) bucket->buflen) {
desired = bucket->buflen - bin; desired = bucket->buflen - bin;
if (desired > data->inbuf_len) { if (desired > data->inbuf_len) {
desired = data->inbuf_len; desired = data->inbuf_len;
@ -221,7 +227,6 @@ static php_stream_filter_status_t php_zlib_deflate_filter(
desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */ desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */
data->strm.next_in = data->inbuf; data->strm.next_in = data->inbuf;
data->strm.avail_in = 0; data->strm.avail_in = 0;
consumed += desired;
bin += desired; bin += desired;
if (data->strm.avail_out < data->outbuf_len) { if (data->strm.avail_out < data->outbuf_len) {
@ -235,6 +240,7 @@ static php_stream_filter_status_t php_zlib_deflate_filter(
exit_status = PSFS_PASS_ON; exit_status = PSFS_PASS_ON;
} }
} }
consumed += bucket->buflen;
php_stream_bucket_delref(bucket TSRMLS_CC); php_stream_bucket_delref(bucket TSRMLS_CC);
} }
@ -258,6 +264,7 @@ static php_stream_filter_status_t php_zlib_deflate_filter(
if (bytes_consumed) { if (bytes_consumed) {
*bytes_consumed = consumed; *bytes_consumed = consumed;
} }
return exit_status; return exit_status;
} }
@ -291,7 +298,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
/* Create this filter */ /* Create this filter */
data = pecalloc(1, sizeof(php_zlib_filter_data), persistent); data = pecalloc(1, sizeof(php_zlib_filter_data), persistent);
if (!data) { if (!data) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zd bytes.", sizeof(php_zlib_filter_data)); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zd bytes", sizeof(php_zlib_filter_data));
return NULL; return NULL;
} }
@ -303,14 +310,14 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
data->strm.avail_out = data->outbuf_len = data->inbuf_len = 2048; data->strm.avail_out = data->outbuf_len = data->inbuf_len = 2048;
data->strm.next_in = data->inbuf = (Bytef *) pemalloc(data->inbuf_len, persistent); data->strm.next_in = data->inbuf = (Bytef *) pemalloc(data->inbuf_len, persistent);
if (!data->inbuf) { if (!data->inbuf) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zd bytes.", data->inbuf_len); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zd bytes", data->inbuf_len);
pefree(data, persistent); pefree(data, persistent);
return NULL; return NULL;
} }
data->strm.avail_in = 0; data->strm.avail_in = 0;
data->strm.next_out = data->outbuf = (Bytef *) pemalloc(data->outbuf_len, persistent); data->strm.next_out = data->outbuf = (Bytef *) pemalloc(data->outbuf_len, persistent);
if (!data->outbuf) { if (!data->outbuf) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zd bytes.", data->outbuf_len); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zd bytes", data->outbuf_len);
pefree(data->inbuf, persistent); pefree(data->inbuf, persistent);
pefree(data, persistent); pefree(data, persistent);
return NULL; return NULL;
@ -409,7 +416,7 @@ factory_setlevel:
} }
break; break;
default: default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid filter parameter, ignored."); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid filter parameter, ignored");
} }
} }
status = deflateInit2(&(data->strm), level, Z_DEFLATED, windowBits, memLevel, 0); status = deflateInit2(&(data->strm), level, Z_DEFLATED, windowBits, memLevel, 0);

View file

@ -96,7 +96,7 @@ static int php_gziop_flush(php_stream *stream TSRMLS_DC)
return gzflush(self->gz_file, Z_SYNC_FLUSH); return gzflush(self->gz_file, Z_SYNC_FLUSH);
} }
static php_stream_ops php_stream_gzio_ops = { php_stream_ops php_stream_gzio_ops = {
php_gziop_write, php_gziop_read, php_gziop_write, php_gziop_read,
php_gziop_close, php_gziop_flush, php_gziop_close, php_gziop_flush,
"ZLIB", "ZLIB",

View file

@ -532,8 +532,8 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
int http_response_code; int http_response_code;
if (SG(headers_sent) && !SG(request_info).no_headers) { if (SG(headers_sent) && !SG(request_info).no_headers) {
char *output_start_filename = php_get_output_start_filename(TSRMLS_C); char *output_start_filename = php_output_get_start_filename(TSRMLS_C);
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C); int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);
if (output_start_filename) { if (output_start_filename) {
sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent by (output started at %s:%d)", sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent by (output started at %s:%d)",

View file

@ -972,14 +972,7 @@ static void php_error_cb(int type, const char *error_filename, const uint error_
efree(log_buffer); efree(log_buffer);
} }
if (PG(display_errors) if (PG(display_errors) && ((module_initialized && !PG(during_request_startup)) || (PG(display_startup_errors)))) {
&& ((module_initialized && !PG(during_request_startup))
|| (PG(display_startup_errors)
&& (OG(php_body_write)==php_default_output_func || OG(php_body_write)==php_ub_body_write_no_header || OG(php_body_write)==php_ub_body_write)
)
)
) {
if (PG(xmlrpc_errors)) { if (PG(xmlrpc_errors)) {
php_printf("<?xml version=\"1.0\"?><methodResponse><fault><value><struct><member><name>faultCode</name><value><int>%ld</int></value></member><member><name>faultString</name><value><string>%s:%s in %s on line %d</string></value></member></struct></value></fault></methodResponse>", PG(xmlrpc_error_number), error_type_str, buffer, error_filename, error_lineno); php_printf("<?xml version=\"1.0\"?><methodResponse><fault><value><struct><member><name>faultCode</name><value><int>%ld</int></value></member><member><name>faultString</name><value><string>%s:%s in %s on line %d</string></value></member></struct></value></fault></methodResponse>", PG(xmlrpc_error_number), error_type_str, buffer, error_filename, error_lineno);
} else { } else {
@ -1456,15 +1449,16 @@ int php_request_startup(TSRMLS_D)
} }
if (PG(output_handler) && PG(output_handler)[0]) { if (PG(output_handler) && PG(output_handler)[0]) {
php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC); zval *oh;
MAKE_STD_ZVAL(oh);
ZVAL_STRING(oh, PG(output_handler), 1);
php_output_start_user(oh, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
zval_ptr_dtor(&oh);
} else if (PG(output_buffering)) { } else if (PG(output_buffering)) {
if (PG(output_buffering)>1) { php_output_start_user(NULL, PG(output_buffering) > 1 ? PG(output_buffering) : 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
php_start_ob_buffer(NULL, PG(output_buffering), 1 TSRMLS_CC);
} else {
php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
}
} else if (PG(implicit_flush)) { } else if (PG(implicit_flush)) {
php_start_implicit_flush(TSRMLS_C); php_output_set_implicit_flush(1 TSRMLS_CC);
} }
/* We turn this off in php_execute_script() */ /* We turn this off in php_execute_script() */
@ -1500,7 +1494,6 @@ int php_request_startup(TSRMLS_D)
zend_try { zend_try {
PG(during_request_startup) = 1; PG(during_request_startup) = 1;
php_output_activate(TSRMLS_C);
if (PG(expose_php)) { if (PG(expose_php)) {
sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1); sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
} }
@ -1626,14 +1619,22 @@ void php_request_shutdown(void *dummy)
/* 3. Flush all output buffers */ /* 3. Flush all output buffers */
zend_try { zend_try {
zend_bool send_buffer = SG(request_info).headers_only ? 0 : 1; zend_bool send_buffer = SG(request_info).headers_only ? 0 : 1;
if (CG(unclean_shutdown) && PG(last_error_type) == E_ERROR && if (CG(unclean_shutdown) && PG(last_error_type) == E_ERROR &&
OG(ob_nesting_level) && !OG(active_ob_buffer).chunk_size && PG(memory_limit) < zend_memory_usage(1 TSRMLS_CC)) { PG(memory_limit) < zend_memory_usage(1 TSRMLS_CC)
) {
send_buffer = 0; send_buffer = 0;
} }
php_end_ob_buffers(send_buffer TSRMLS_CC);
if (!send_buffer) {
php_output_discard_all(TSRMLS_C);
} else {
php_output_end_all(TSRMLS_C);
}
php_output_deactivate(TSRMLS_C);
} zend_end_try(); } zend_end_try();
/* 4. Send the set HTTP headers (note: This must be done AFTER php_end_ob_buffers() !!) */ /* 4. Send the set HTTP headers (note: This must be done AFTER php_output_discard_all() / php_output_end_all() !!) */
zend_try { zend_try {
sapi_send_headers(TSRMLS_C); sapi_send_headers(TSRMLS_C);
} zend_end_try(); } zend_end_try();
@ -1720,12 +1721,12 @@ PHPAPI void php_com_initialize(TSRMLS_D)
} }
/* }}} */ /* }}} */
/* {{{ php_body_write_wrapper /* {{{ php_output_wrapper
*/ */
static int php_body_write_wrapper(const char *str, uint str_length) static int php_output_wrapper(const char *str, uint str_length)
{ {
TSRMLS_FETCH(); TSRMLS_FETCH();
return php_body_write(str, str_length TSRMLS_CC); return php_output_write(str, str_length TSRMLS_CC);
} }
/* }}} */ /* }}} */
@ -1872,7 +1873,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
zuf.error_function = php_error_cb; zuf.error_function = php_error_cb;
zuf.printf_function = php_printf; zuf.printf_function = php_printf;
zuf.write_function = php_body_write_wrapper; zuf.write_function = php_output_wrapper;
zuf.fopen_function = php_fopen_wrapper_for_zend; zuf.fopen_function = php_fopen_wrapper_for_zend;
zuf.message_handler = php_message_handler_for_zend; zuf.message_handler = php_message_handler_for_zend;
zuf.block_interruptions = sapi_module.block_interruptions; zuf.block_interruptions = sapi_module.block_interruptions;
@ -2213,17 +2214,22 @@ void php_module_shutdown(TSRMLS_D)
#ifndef ZTS #ifndef ZTS
zend_ini_shutdown(TSRMLS_C); zend_ini_shutdown(TSRMLS_C);
shutdown_memory_manager(CG(unclean_shutdown), 1 TSRMLS_CC); shutdown_memory_manager(CG(unclean_shutdown), 1 TSRMLS_CC);
core_globals_dtor(&core_globals TSRMLS_CC);
gc_globals_dtor(TSRMLS_C);
#else #else
zend_ini_global_shutdown(TSRMLS_C); zend_ini_global_shutdown(TSRMLS_C);
ts_free_id(core_globals_id);
#endif #endif
php_output_shutdown();
php_shutdown_temporary_directory(); php_shutdown_temporary_directory();
module_initialized = 0; module_initialized = 0;
#ifndef ZTS
core_globals_dtor(&core_globals TSRMLS_CC);
gc_globals_dtor(TSRMLS_C);
#else
ts_free_id(core_globals_id);
#endif
#if defined(PHP_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1400) #if defined(PHP_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1400)
if (old_invalid_parameter_handler == NULL) { if (old_invalid_parameter_handler == NULL) {
_set_invalid_parameter_handler(old_invalid_parameter_handler); _set_invalid_parameter_handler(old_invalid_parameter_handler);
@ -2384,7 +2390,7 @@ PHPAPI void php_handle_aborted_connection(void)
TSRMLS_FETCH(); TSRMLS_FETCH();
PG(connection_status) = PHP_CONNECTION_ABORTED; PG(connection_status) = PHP_CONNECTION_ABORTED;
php_output_set_status(0 TSRMLS_CC); php_output_set_status(PHP_OUTPUT_DISABLED TSRMLS_CC);
if (!PG(ignore_user_abort)) { if (!PG(ignore_user_abort)) {
zend_bailout(); zend_bailout();

File diff suppressed because it is too large Load diff

View file

@ -384,20 +384,7 @@ END_EXTERN_C()
/* Output support */ /* Output support */
#include "main/php_output.h" #include "main/php_output.h"
#define PHPWRITE(str, str_len) php_body_write((str), (str_len) TSRMLS_CC)
#define PUTS(str) do { \
const char *__str = (str); \
php_body_write(__str, strlen(__str) TSRMLS_CC); \
} while (0)
#define PUTC(c) (php_body_write(&(c), 1 TSRMLS_CC), (c))
#define PHPWRITE_H(str, str_len) php_header_write((str), (str_len) TSRMLS_CC)
#define PUTS_H(str) do { \
const char *__str = (str); \
php_header_write(__str, strlen(__str) TSRMLS_CC); \
} while (0)
#define PUTC_H(c) (php_header_write(&(c), 1 TSRMLS_CC), (c))
#include "php_streams.h" #include "php_streams.h"
#include "php_memory_streams.h" #include "php_memory_streams.h"

View file

@ -85,7 +85,7 @@ int php_info_logos(const char *logo_string TSRMLS_DC)
content_header[len] = '\0'; content_header[len] = '\0';
sapi_add_header(content_header, len, 0); sapi_add_header(content_header, len, 0);
PHPWRITE(logo_image->data, logo_image->size); PHPWRITE((char*)logo_image->data, logo_image->size);
return 1; return 1;
} }

View file

@ -12,7 +12,7 @@
| obtain it through the world-wide-web, please send a note to | | obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author: Zeev Suraski <zeev@zend.com> | | Author: Michael Wallner <mike@php.net> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
*/ */
@ -21,35 +21,230 @@
#ifndef PHP_OUTPUT_H #ifndef PHP_OUTPUT_H
#define PHP_OUTPUT_H #define PHP_OUTPUT_H
#define PHP_OUTPUT_NEWAPI 1
/* handler ops */
#define PHP_OUTPUT_HANDLER_WRITE 0x00 /* standard passthru */
#define PHP_OUTPUT_HANDLER_START 0x01 /* start */
#define PHP_OUTPUT_HANDLER_CLEAN 0x02 /* restart */
#define PHP_OUTPUT_HANDLER_FLUSH 0x04 /* pass along as much as possible */
#define PHP_OUTPUT_HANDLER_FINAL 0x08 /* finalize */
#define PHP_OUTPUT_HANDLER_CONT PHP_OUTPUT_HANDLER_WRITE
#define PHP_OUTPUT_HANDLER_END PHP_OUTPUT_HANDLER_FINAL
/* handler types */
#define PHP_OUTPUT_HANDLER_INTERNAL 0x0000
#define PHP_OUTPUT_HANDLER_USER 0x0001
/* handler ability flags */
#define PHP_OUTPUT_HANDLER_CLEANABLE 0x0010
#define PHP_OUTPUT_HANDLER_FLUSHABLE 0x0020
#define PHP_OUTPUT_HANDLER_REMOVABLE 0x0040
#define PHP_OUTPUT_HANDLER_STDFLAGS 0x0070
/* handler status flags */
#define PHP_OUTPUT_HANDLER_STARTED 0x1000
#define PHP_OUTPUT_HANDLER_DISABLED 0x2000
/* handler op return values */
typedef enum _php_output_handler_status_t {
PHP_OUTPUT_HANDLER_FAILURE,
PHP_OUTPUT_HANDLER_SUCCESS,
PHP_OUTPUT_HANDLER_NO_DATA,
} php_output_handler_status_t;
/* php_output_stack_pop() flags */
#define PHP_OUTPUT_POP_TRY 0x000
#define PHP_OUTPUT_POP_FORCE 0x001
#define PHP_OUTPUT_POP_DISCARD 0x010
#define PHP_OUTPUT_POP_SILENT 0x100
/* real global flags */
#define PHP_OUTPUT_IMPLICITFLUSH 0x01
#define PHP_OUTPUT_DISABLED 0x02
#define PHP_OUTPUT_WRITTEN 0x04
#define PHP_OUTPUT_SENT 0x08
/* supplementary flags for php_output_get_status() */
#define PHP_OUTPUT_ACTIVE 0x10
#define PHP_OUTPUT_LOCKED 0x20
/* handler hooks */
typedef enum _php_output_handler_hook_t {
PHP_OUTPUT_HANDLER_HOOK_GET_OPAQ,
PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS,
PHP_OUTPUT_HANDLER_HOOK_GET_LEVEL,
PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE,
PHP_OUTPUT_HANDLER_HOOK_DISABLE,
/* unused */
PHP_OUTPUT_HANDLER_HOOK_LAST,
} php_output_handler_hook_t;
#define PHP_OUTPUT_HANDLER_INITBUF_SIZE(s) \
( (s) ? \
(s) + PHP_OUTPUT_HANDLER_ALIGNTO_SIZE - ((s) % (PHP_OUTPUT_HANDLER_ALIGNTO_SIZE)) : \
PHP_OUTPUT_HANDLER_DEFAULT_SIZE \
)
#define PHP_OUTPUT_HANDLER_ALIGNTO_SIZE 0x1000
#define PHP_OUTPUT_HANDLER_DEFAULT_SIZE 0x4000
typedef struct _php_output_buffer {
char *data;
size_t size;
size_t used;
uint free:1;
uint _res:31;
} php_output_buffer;
typedef struct _php_output_context {
int op;
php_output_buffer in;
php_output_buffer out;
#ifdef ZTS
void ***tsrm_ls;
#endif
} php_output_context;
#define PHP_OUTPUT_TSRMLS(ctx) TSRMLS_FETCH_FROM_CTX((ctx)->tsrm_ls)
/* old-style, stateless callback */
typedef void (*php_output_handler_func_t)(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC); typedef void (*php_output_handler_func_t)(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC);
/* new-style, opaque context callback */
typedef int (*php_output_handler_context_func_t)(void **handler_context, php_output_context *output_context);
/* output handler context dtor */
typedef void (*php_output_handler_context_dtor_t)(void *opaq TSRMLS_DC);
/* conflict check callback */
typedef int (*php_output_handler_conflict_check_t)(const char *handler_name, size_t handler_name_len TSRMLS_DC);
/* ctor for aliases */
typedef struct _php_output_handler *(*php_output_handler_alias_ctor_t)(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC);
typedef struct _php_output_handler_user_func_t {
zend_fcall_info fci;
zend_fcall_info_cache fcc;
zval *zoh;
} php_output_handler_user_func_t;
typedef struct _php_output_handler {
char *name;
size_t name_len;
int flags;
int level;
size_t size;
php_output_buffer buffer;
void *opaq;
void (*dtor)(void *opaq TSRMLS_DC);
union {
php_output_handler_user_func_t *user;
php_output_handler_context_func_t internal;
} func;
} php_output_handler;
PHPAPI const char php_output_default_handler_name[sizeof("default output handler")];
PHPAPI const char php_output_devnull_handler_name[sizeof("null output handler")];
ZEND_BEGIN_MODULE_GLOBALS(output)
int flags;
zend_stack *handlers;
php_output_handler *active;
php_output_handler *running;
char *output_start_filename;
int output_start_lineno;
ZEND_END_MODULE_GLOBALS(output);
/* there should not be a need to use OG() from outside of output.c */
#ifdef ZTS
# define OG(v) TSRMG(output_globals_id, zend_output_globals *, v)
#else
# define OG(v) (output_globals.v)
#endif
/* convenience macros */
#define PHPWRITE(str, str_len) php_output_write((str), (str_len) TSRMLS_CC)
#define PHPWRITE_H(str, str_len) php_output_write_unbuffered((str), (str_len) TSRMLS_CC)
#define PUTC(c) (php_output_write(&(c), 1 TSRMLS_CC), (c))
#define PUTC_H(c) (php_output_write_unbuffered(&(c), 1 TSRMLS_CC), (c))
#define PUTS(str) do { \
const char *__str = (str); \
php_output_write(__str, strlen(__str) TSRMLS_CC); \
} while (0)
#define PUTS_H(str) do { \
const char *__str = (str); \
php_output_write_unbuffered(__str, strlen(__str) TSRMLS_CC); \
} while (0)
BEGIN_EXTERN_C() BEGIN_EXTERN_C()
#define php_output_tearup() \
php_output_startup(); \
php_output_activate(TSRMLS_C)
#define php_output_teardown() \
php_output_end_all(TSRMLS_C); \
php_output_deactivate(TSRMLS_C); \
php_output_shutdown()
/* MINIT */
PHPAPI void php_output_startup(void); PHPAPI void php_output_startup(void);
PHPAPI void php_output_activate(TSRMLS_D); /* MSHUTDOWN */
PHPAPI void php_output_set_status(zend_bool status TSRMLS_DC); PHPAPI void php_output_shutdown(void);
PHPAPI void php_output_register_constants(TSRMLS_D); PHPAPI void php_output_register_constants(TSRMLS_D);
PHPAPI int php_default_output_func(const char *str, uint str_len TSRMLS_DC);
PHPAPI int php_ub_body_write(const char *str, uint str_length TSRMLS_DC); /* RINIT */
PHPAPI int php_ub_body_write_no_header(const char *str, uint str_length TSRMLS_DC); PHPAPI int php_output_activate(TSRMLS_D);
PHPAPI int php_body_write(const char *str, uint str_length TSRMLS_DC); /* RSHUTDOWN */
PHPAPI int php_header_write(const char *str, uint str_length TSRMLS_DC); PHPAPI void php_output_deactivate(TSRMLS_D);
PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC);
PHPAPI int php_start_ob_buffer_named(const char *output_handler_name, uint chunk_size, zend_bool erase TSRMLS_DC); PHPAPI void php_output_set_status(int status TSRMLS_DC);
PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS_DC); PHPAPI int php_output_get_status(TSRMLS_D);
PHPAPI void php_end_ob_buffers(zend_bool send_buffer TSRMLS_DC); PHPAPI void php_output_set_implicit_flush(int flush TSRMLS_DC);
PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC); PHPAPI char *php_output_get_start_filename(TSRMLS_D);
PHPAPI int php_ob_get_length(zval *p TSRMLS_DC); PHPAPI int php_output_get_start_lineno(TSRMLS_D);
PHPAPI void php_start_implicit_flush(TSRMLS_D);
PHPAPI void php_end_implicit_flush(TSRMLS_D); PHPAPI int php_output_write_unbuffered(const char *str, size_t len TSRMLS_DC);
PHPAPI char *php_get_output_start_filename(TSRMLS_D); PHPAPI int php_output_write(const char *str, size_t len TSRMLS_DC);
PHPAPI int php_get_output_start_lineno(TSRMLS_D);
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); PHPAPI int php_output_flush(TSRMLS_D);
PHPAPI int php_ob_handler_used(char *handler_name TSRMLS_DC); PHPAPI void php_output_flush_all(TSRMLS_D);
PHPAPI int php_ob_init_conflict(char *handler_new, char *handler_set TSRMLS_DC); PHPAPI int php_output_clean(TSRMLS_D);
PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC); PHPAPI void php_output_clean_all(TSRMLS_D);
PHPAPI int php_ob_get_length(zval *p TSRMLS_DC); PHPAPI int php_output_end(TSRMLS_D);
PHPAPI void php_output_end_all(TSRMLS_D);
PHPAPI int php_output_discard(TSRMLS_D);
PHPAPI void php_output_discard_all(TSRMLS_D);
PHPAPI int php_output_get_contents(zval *p TSRMLS_DC);
PHPAPI int php_output_get_length(zval *p TSRMLS_DC);
PHPAPI int php_output_get_level(TSRMLS_D);
PHPAPI int php_output_start_default(TSRMLS_D);
PHPAPI int php_output_start_devnull(TSRMLS_D);
PHPAPI int php_output_start_user(zval *output_handler, size_t chunk_size, int flags TSRMLS_DC);
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 TSRMLS_DC);
PHPAPI php_output_handler *php_output_handler_create_user(zval *handler, size_t chunk_size, int flags TSRMLS_DC);
PHPAPI php_output_handler *php_output_handler_create_internal(const char *name, size_t name_len, php_output_handler_context_func_t handler, size_t chunk_size, int flags TSRMLS_DC);
PHPAPI void php_output_handler_set_context(php_output_handler *handler, void *opaq, void (*dtor)(void* TSRMLS_DC) TSRMLS_DC);
PHPAPI int php_output_handler_start(php_output_handler *handler TSRMLS_DC);
PHPAPI int php_output_handler_started(const char *name, size_t name_len TSRMLS_DC);
PHPAPI int php_output_handler_hook(php_output_handler_hook_t type, void *arg TSRMLS_DC);
PHPAPI void php_output_handler_dtor(php_output_handler *handler TSRMLS_DC);
PHPAPI void php_output_handler_free(php_output_handler **handler TSRMLS_DC);
PHPAPI int php_output_handler_conflict(const char *handler_new, size_t handler_new_len, const char *handler_set, size_t handler_set_len TSRMLS_DC);
PHPAPI int php_output_handler_conflict_register(const char *handler_name, size_t handler_name_len, php_output_handler_conflict_check_t check_func TSRMLS_DC);
PHPAPI int php_output_handler_reverse_conflict_register(const char *handler_name, size_t handler_name_len, php_output_handler_conflict_check_t check_func TSRMLS_DC);
PHPAPI php_output_handler_alias_ctor_t *php_output_handler_alias(const char *handler_name, size_t handler_name_len TSRMLS_DC);
PHPAPI int php_output_handler_alias_register(const char *handler_name, size_t handler_name_len, php_output_handler_alias_ctor_t func TSRMLS_DC);
END_EXTERN_C() END_EXTERN_C()
PHP_FUNCTION(ob_start); PHP_FUNCTION(ob_start);
PHP_FUNCTION(ob_flush); PHP_FUNCTION(ob_flush);
PHP_FUNCTION(ob_clean); PHP_FUNCTION(ob_clean);
@ -64,51 +259,16 @@ PHP_FUNCTION(ob_get_status);
PHP_FUNCTION(ob_implicit_flush); PHP_FUNCTION(ob_implicit_flush);
PHP_FUNCTION(ob_list_handlers); PHP_FUNCTION(ob_list_handlers);
typedef struct _php_ob_buffer {
char *buffer;
uint size;
uint text_length;
int block_size;
uint chunk_size;
int status;
zval *output_handler;
php_output_handler_func_t internal_output_handler;
char *internal_output_handler_buffer;
uint internal_output_handler_buffer_size;
char *handler_name;
zend_bool erase;
} php_ob_buffer;
typedef struct _php_output_globals {
int (*php_body_write)(const char *str, uint str_length TSRMLS_DC); /* string output */
int (*php_header_write)(const char *str, uint str_length TSRMLS_DC); /* unbuffer string output */
php_ob_buffer active_ob_buffer;
unsigned char implicit_flush;
char *output_start_filename;
int output_start_lineno;
zend_stack ob_buffers;
int ob_nesting_level;
zend_bool ob_lock;
zend_bool disable_output;
} php_output_globals;
#ifdef ZTS
#define OG(v) TSRMG(output_globals_id, php_output_globals *, v)
ZEND_API extern int output_globals_id;
#else
#define OG(v) (output_globals.v)
ZEND_API extern php_output_globals output_globals;
#endif
#define PHP_OUTPUT_HANDLER_START (1<<0)
#define PHP_OUTPUT_HANDLER_CONT (1<<1)
#define PHP_OUTPUT_HANDLER_END (1<<2)
#define PHP_OUTPUT_HANDLER_INTERNAL 0
#define PHP_OUTPUT_HANDLER_USER 1
PHP_FUNCTION(output_add_rewrite_var); PHP_FUNCTION(output_add_rewrite_var);
PHP_FUNCTION(output_reset_rewrite_vars); PHP_FUNCTION(output_reset_rewrite_vars);
#endif
#endif /* PHP_OUTPUT_H */ /*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/

View file

@ -329,7 +329,7 @@ static void php_apache_request_shutdown(void *dummy)
{ {
TSRMLS_FETCH(); TSRMLS_FETCH();
php_output_set_status(0 TSRMLS_CC); php_output_set_status(PHP_OUTPUT_DISABLED TSRMLS_CC);
if (AP(in_request)) { if (AP(in_request)) {
AP(in_request) = 0; AP(in_request) = 0;
php_request_shutdown(dummy); php_request_shutdown(dummy);

View file

@ -368,7 +368,7 @@ PHP_FUNCTION(virtual)
RETURN_FALSE; RETURN_FALSE;
} }
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
php_header(TSRMLS_C); php_header(TSRMLS_C);
if (run_sub_req(rr)) { if (run_sub_req(rr)) {

View file

@ -91,7 +91,7 @@ PHP_FUNCTION(virtual)
} }
/* Flush everything. */ /* Flush everything. */
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
php_header(TSRMLS_C); php_header(TSRMLS_C);
/* Ensure that the ap_r* layer for the main request is flushed, to /* Ensure that the ap_r* layer for the main request is flushed, to

View file

@ -453,7 +453,7 @@ static void php_apache_request_shutdown(void *dummy)
{ {
TSRMLS_FETCH(); TSRMLS_FETCH();
AP(current_hook) = AP_CLEANUP; AP(current_hook) = AP_CLEANUP;
php_output_set_status(0 TSRMLS_CC); php_output_set_status(PHP_OUTPUT_DISABLED TSRMLS_CC);
SG(server_context) = NULL; /* The server context (request) is invalid by the time run_cleanups() is called */ SG(server_context) = NULL; /* The server context (request) is invalid by the time run_cleanups() is called */
if(SG(sapi_started)) { if(SG(sapi_started)) {
php_request_shutdown(dummy); php_request_shutdown(dummy);

View file

@ -1734,7 +1734,7 @@ PHP_FUNCTION(virtual)
RETURN_FALSE; RETURN_FALSE;
} }
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
php_header(TSRMLS_C); php_header(TSRMLS_C);
if (run_sub_req(rr)) { if (run_sub_req(rr)) {

View file

@ -1812,11 +1812,9 @@ consult the installation file that came with this distribution, or visit \n\
case '?': case '?':
fcgi_shutdown(); fcgi_shutdown();
no_headers = 1; no_headers = 1;
php_output_startup();
php_output_activate(TSRMLS_C);
SG(headers_sent) = 1; SG(headers_sent) = 1;
php_cgi_usage(argv[0]); php_cgi_usage(argv[0]);
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
exit_status = 0; exit_status = 0;
goto out; goto out;
} }
@ -1890,15 +1888,13 @@ consult the installation file that came with this distribution, or visit \n\
if (script_file) { if (script_file) {
efree(script_file); efree(script_file);
} }
php_output_startup();
php_output_activate(TSRMLS_C);
SG(headers_sent) = 1; SG(headers_sent) = 1;
php_printf("[PHP Modules]\n"); php_printf("[PHP Modules]\n");
print_modules(TSRMLS_C); print_modules(TSRMLS_C);
php_printf("\n[Zend Modules]\n"); php_printf("\n[Zend Modules]\n");
print_extensions(TSRMLS_C); print_extensions(TSRMLS_C);
php_printf("\n"); php_printf("\n");
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
exit_status = 0; exit_status = 0;
goto out; goto out;
@ -2117,7 +2113,7 @@ consult the installation file that came with this distribution, or visit \n\
if (open_file_for_scanning(&file_handle TSRMLS_CC) == SUCCESS) { if (open_file_for_scanning(&file_handle TSRMLS_CC) == SUCCESS) {
zend_strip(TSRMLS_C); zend_strip(TSRMLS_C);
zend_file_handle_dtor(&file_handle TSRMLS_CC); zend_file_handle_dtor(&file_handle TSRMLS_CC);
php_end_ob_buffers(1 TSRMLS_CC); php_output_teardown();
} }
return SUCCESS; return SUCCESS;
break; break;
@ -2132,7 +2128,7 @@ consult the installation file that came with this distribution, or visit \n\
goto fastcgi_request_done; goto fastcgi_request_done;
} }
zend_file_handle_dtor(&file_handle TSRMLS_CC); zend_file_handle_dtor(&file_handle TSRMLS_CC);
php_end_ob_buffers(1 TSRMLS_CC); php_output_teardown();
} }
return SUCCESS; return SUCCESS;
} }
@ -2143,6 +2139,7 @@ consult the installation file that came with this distribution, or visit \n\
open_file_for_scanning(&file_handle TSRMLS_CC); open_file_for_scanning(&file_handle TSRMLS_CC);
zend_indent(); zend_indent();
zend_file_handle_dtor(&file_handle TSRMLS_CC); zend_file_handle_dtor(&file_handle TSRMLS_CC);
php_output_teardown();
return SUCCESS; return SUCCESS;
break; break;
#endif #endif

View file

@ -822,7 +822,7 @@ int main(int argc, char *argv[])
} }
request_started = 1; request_started = 1;
php_cli_usage(argv[0]); php_cli_usage(argv[0]);
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
exit_status=0; exit_status=0;
goto out; goto out;
@ -832,7 +832,7 @@ int main(int argc, char *argv[])
} }
request_started = 1; request_started = 1;
php_print_info(0xFFFFFFFF TSRMLS_CC); php_print_info(0xFFFFFFFF TSRMLS_CC);
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
exit_status=0; exit_status=0;
goto out; goto out;
@ -846,7 +846,7 @@ int main(int argc, char *argv[])
php_printf("\n[Zend Modules]\n"); php_printf("\n[Zend Modules]\n");
print_extensions(TSRMLS_C); print_extensions(TSRMLS_C);
php_printf("\n"); php_printf("\n");
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
exit_status=0; exit_status=0;
goto out; goto out;
@ -869,7 +869,7 @@ int main(int argc, char *argv[])
#endif #endif
get_zend_version() get_zend_version()
); );
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
exit_status=0; exit_status=0;
goto out; goto out;

View file

@ -1040,11 +1040,10 @@ int main(int argc, char *argv[])
while ((c=ap_php_getopt(argc, argv, OPTSTRING))!=-1) { while ((c=ap_php_getopt(argc, argv, OPTSTRING))!=-1) {
switch (c) { switch (c) {
case '?': case '?':
php_output_startup(); php_output_tearup();
php_output_activate(TSRMLS_C);
SG(headers_sent) = 1; SG(headers_sent) = 1;
php_milter_usage(argv[0]); php_milter_usage(argv[0]);
php_end_ob_buffers(1 TSRMLS_CC); php_output_teardown();
exit(1); exit(1);
break; break;
} }
@ -1088,11 +1087,10 @@ int main(int argc, char *argv[])
case 'h': /* help & quit */ case 'h': /* help & quit */
case '?': case '?':
php_output_startup(); php_output_tearup();
php_output_activate(TSRMLS_C);
SG(headers_sent) = 1; SG(headers_sent) = 1;
php_milter_usage(argv[0]); php_milter_usage(argv[0]);
php_end_ob_buffers(1 TSRMLS_CC); php_output_teardown();
exit(1); exit(1);
break; break;
@ -1112,7 +1110,7 @@ int main(int argc, char *argv[])
SG(headers_sent) = 1; SG(headers_sent) = 1;
SG(request_info).no_headers = 1; SG(request_info).no_headers = 1;
php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2010 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2010 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
php_end_ob_buffers(1 TSRMLS_CC); php_output_teardown();
exit(1); exit(1);
break; break;

View file

@ -347,7 +347,7 @@ PHP_FUNCTION(nsapi_virtual)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - Sub-requests do not work with zlib.output_compression", uri); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - Sub-requests do not work with zlib.output_compression", uri);
RETURN_FALSE; RETURN_FALSE;
} else { } else {
php_end_ob_buffers(1 TSRMLS_CC); php_output_end_all(TSRMLS_C);
php_header(TSRMLS_C); php_header(TSRMLS_C);
/* do the sub-request */ /* do the sub-request */

View file

@ -18,10 +18,10 @@ echo 'Done';
?> ?>
--EXPECTF-- --EXPECTF--
[callback:1]Attempt to flush unerasable buffer - should fail... [callback:1]Attempt to flush unerasable buffer - should fail...
Notice: ob_flush(): failed to flush buffer callback. in %s on line %d Notice: ob_flush(): failed to flush buffer of callback (0) in %s on line %d
bool(false) bool(false)
string(%d) "Attempt to flush unerasable buffer - should fail... string(%d) "Attempt to flush unerasable buffer - should fail...
Notice: ob_flush(): failed to flush buffer callback. in %s on line %d Notice: ob_flush(): failed to flush buffer of callback (0) in %s on line %d
bool(false) bool(false)
" "
Done Done

View file

@ -1,7 +1,5 @@
--TEST-- --TEST--
output buffering - fatalism output buffering - fatalism
--XFAIL--
This test will fail until the fix in revision r214155 is backported from php 6
--FILE-- --FILE--
<?php <?php
function obh($s) function obh($s)

View file

@ -37,67 +37,69 @@ Array
) )
Array Array
( (
[level] => 5
[type] => 1
[status] => 1
[name] => d [name] => d
[del] => 1 [type] => 1
[flags] => 4209
[level] => 4
[chunk_size] => %d
[buffer_size] => 16384
[buffer_used] => 96
) )
Array Array
( (
[0] => Array [0] => Array
( (
[chunk_size] => 0
[size] => 40960
[block_size] => 10240
[type] => 1
[status] => 0
[name] => default output handler [name] => default output handler
[del] => 1 [type] => 0
[flags] => 112
[level] => 0
[chunk_size] => %d
[buffer_size] => 16384
[buffer_used] => 0
) )
[1] => Array [1] => Array
( (
[chunk_size] => 0
[size] => 40960
[block_size] => 10240
[type] => 1
[status] => 0
[name] => a [name] => a
[del] => 1 [type] => 1
[flags] => 113
[level] => 1
[chunk_size] => %d
[buffer_size] => 16384
[buffer_used] => 0
) )
[2] => Array [2] => Array
( (
[chunk_size] => 0
[size] => 40960
[block_size] => 10240
[type] => 1
[status] => 0
[name] => b [name] => b
[del] => 1 [type] => 1
[flags] => 113
[level] => 2
[chunk_size] => %d
[buffer_size] => 16384
[buffer_used] => 0
) )
[3] => Array [3] => Array
( (
[chunk_size] => 0
[size] => 40960
[block_size] => 10240
[type] => 1
[status] => 0
[name] => c [name] => c
[del] => 1 [type] => 1
[flags] => 113
[level] => 3
[chunk_size] => %d
[buffer_size] => 16384
[buffer_used] => 4
) )
[4] => Array [4] => Array
( (
[chunk_size] => 0
[size] => 40960
[block_size] => 10240
[type] => 1
[status] => 1
[name] => d [name] => d
[del] => 1 [type] => 1
[flags] => 4209
[level] => 4
[chunk_size] => %d
[buffer_size] => 16384
[buffer_used] => %d
) )
) )

View file

@ -24,11 +24,11 @@ yes!
yes! yes!
Array Array
( (
[0] => 3: yes [0] => 1: yes
[1] => 2: ! [1] => 4: !
[2] => 2: no [2] => 2:
[3] => 2: yes! [3] => 0: yes!
[4] => 4: no [4] => 10:
) )

View file

@ -29,8 +29,8 @@ echo "Done";
-- Testing ob_clean() function with Zero arguments -- -- Testing ob_clean() function with Zero arguments --
Notice: ob_clean(): failed to delete buffer. No buffer to delete. in %s on line 12 Notice: ob_clean(): failed to delete buffer. No buffer to delete in %s on line 12
bool(false) bool(false)
string(61) "bool(true) string(61) "bool(true)
Ensure the buffer is still active after the clean." Ensure the buffer is still active after the clean."
Done Done

View file

@ -21,11 +21,11 @@ var_dump(ob_end_clean());
?> ?>
--EXPECTF-- --EXPECTF--
Notice: ob_end_clean(): failed to delete buffer. No buffer to delete. in %s on line 7 Notice: ob_end_clean(): failed to delete buffer. No buffer to delete in %s on line 7
bool(false) bool(false)
bool(true) bool(true)
bool(true) bool(true)
Notice: ob_end_clean(): failed to delete buffer. No buffer to delete. in %s on line 16 Notice: ob_end_clean(): failed to delete buffer. No buffer to delete in %s on line 16
bool(false) bool(false)

View file

@ -30,12 +30,12 @@ echo "Done";
-- Testing ob_end_flush() function with Zero arguments -- -- Testing ob_end_flush() function with Zero arguments --
Notice: ob_end_flush(): failed to delete and flush buffer. No buffer to delete or flush. in %s on line 12 Notice: ob_end_flush(): failed to delete and flush buffer. No buffer to delete or flush in %s on line 12
bool(false) bool(false)
bool(true) bool(true)
Hello Hello
bool(true) bool(true)
Notice: ob_end_flush(): failed to delete and flush buffer. No buffer to delete or flush. in %s on line 21 Notice: ob_end_flush(): failed to delete and flush buffer. No buffer to delete or flush in %s on line 21
bool(false) bool(false)
Done Done

View file

@ -30,10 +30,10 @@ echo "Done";
-- Testing ob_flush() function with Zero arguments -- -- Testing ob_flush() function with Zero arguments --
Notice: ob_flush(): failed to flush buffer. No buffer to flush. in %s on line 12 Notice: ob_flush(): failed to flush buffer. No buffer to flush in %s on line 12
bool(false) bool(false)
This should get flushed. This should get flushed.
bool(true) bool(true)
Ensure the buffer is still active after the flush. Ensure the buffer is still active after the flush.
bool(true) bool(true)
Done Done

View file

@ -14,5 +14,6 @@ echo "Hello World";
var_dump(ob_get_clean()); var_dump(ob_get_clean());
?> ?>
--EXPECTF-- --EXPECTF--
Notice: ob_get_clean(): failed to delete buffer. No buffer to delete in %s on line 7
bool(false) bool(false)
string(11) "Hello World" string(11) "Hello World"

View file

@ -42,6 +42,6 @@ int(2)
int(1) int(1)
int(0) int(0)
Notice: ob_end_flush(): failed to delete and flush buffer. No buffer to delete or flush. in %s on line 26 Notice: ob_end_flush(): failed to delete and flush buffer. No buffer to delete or flush in %s on line 26
int(0) int(0)
Done Done

View file

@ -15,20 +15,19 @@ var_dump($status);
array(1) { array(1) {
[0]=> [0]=>
array(7) { array(7) {
["chunk_size"]=>
int(0)
["size"]=>
int(40960)
["block_size"]=>
int(10240)
["type"]=>
int(1)
["status"]=>
int(0)
["name"]=> ["name"]=>
string(22) "default output handler" string(22) "default output handler"
["del"]=> ["type"]=>
bool(true) int(0)
["flags"]=>
int(112)
["level"]=>
int(0)
["chunk_size"]=>
int(0)
["buffer_size"]=>
int(16384)
["buffer_used"]=>
int(0)
} }
} }

View file

@ -1,12 +1,12 @@
--TEST-- --TEST--
ob_start() chunk_size: confirm buffer is flushed after any output call that causes its length to equal or exceed chunk_size. ob_start() chunk_size: confirm buffer is flushed after any output call that causes its length to equal or exceed chunk_size.
--FILE-- --FILE--
<?php <?php
/* /*
* proto bool ob_start([ string|array user_function [, int chunk_size [, bool erase]]]) * proto bool ob_start([ string|array user_function [, int chunk_size [, bool erase]]])
* Function is implemented in main/output.c * Function is implemented in main/output.c
*/ */
// In HEAD, $chunk_size value of 1 should not have any special behaviour (http://marc.info/?l=php-internals&m=123476465621346&w=2).
function callback($string) { function callback($string) {
global $callback_invocations; global $callback_invocations;
$callback_invocations++; $callback_invocations++;
@ -40,7 +40,15 @@ f[call:1; len:8]12345678
f[call:1; len:8]12345678 f[call:1; len:8]12345678
----( chunk_size: 1, output append size: 1 )---- ----( chunk_size: 1, output append size: 1 )----
f[call:1; len:8]12345678 f[call:1; len:1]1
f[call:2; len:1]2
f[call:3; len:1]3
f[call:4; len:1]4
f[call:5; len:1]5
f[call:6; len:1]6
f[call:7; len:1]7
f[call:8; len:1]8
f[call:9; len:0]
----( chunk_size: 2, output append size: 1 )---- ----( chunk_size: 2, output append size: 1 )----
f[call:1; len:2]12 f[call:1; len:2]12
@ -85,7 +93,9 @@ f[call:1; len:8]12345678
f[call:1; len:8]12345678 f[call:1; len:8]12345678
----( chunk_size: 1, output append size: 4 )---- ----( chunk_size: 1, output append size: 4 )----
f[call:1; len:8]12345678 f[call:1; len:4]1234
f[call:2; len:4]5678
f[call:3; len:0]
----( chunk_size: 2, output append size: 4 )---- ----( chunk_size: 2, output append size: 4 )----
f[call:1; len:4]1234 f[call:1; len:4]1234

View file

@ -1,5 +1,5 @@
--TEST-- --TEST--
ob_start(): multiple buffer initialization with a single call, using arrays. ob_start(): ensure multiple buffer initialization with a single call using arrays is not supported on PHP6 (http://bugs.php.net/42641)
--FILE-- --FILE--
<?php <?php
/* /*
@ -72,46 +72,37 @@ var_dump(ob_start(array('f', 'C::g', array(array($c, "g"), array($c, "h")))));
checkAndClean(); checkAndClean();
?> ?>
--EXPECTF-- --EXPECTF--
---> Test arrays: ---> Test arrays:
f[call:1; len:34] - bool(true)
Notice: ob_start(): failed to create buffer in %s on line 44
bool(false)
Array Array
( (
[0] => f
) )
f[call:3; len:68] - f[call:2; len:47] - bool(true) Notice: ob_start(): failed to create buffer in %s on line 47
bool(false)
Array Array
( (
[0] => f
[1] => f
) )
Notice: ob_start(): failed to create buffer in %s on line 50
f[call:5; len:150] - C::g[call:2; len:125] - f[call:4; len:103] - C::g[call:1; len:79] - bool(true) bool(false)
Array Array
( (
[0] => f
[1] => C::g
[2] => f
[3] => C::g
) )
Notice: ob_start(): failed to create buffer in %s on line 53
bool(false)
f[call:6; len:35] - bool(false)
Array Array
( (
[0] => f
) )
f[call:7; len:35] - bool(false) Notice: ob_start(): failed to create buffer in %s on line 56
bool(false)
Array Array
( (
[0] => f
) )
C::h[call:1; len:37; id:originalID] - bool(true) C::h[call:1; len:37; id:originalID] - bool(true)
Array Array
( (
@ -124,11 +115,9 @@ Array
[0] => C::h [0] => C::h
) )
f[call:8; len:175] - C::g[call:4; len:150] - C::g[call:3; len:125] - C::h[call:3; len:82; id:changedIDagain] - bool(true)
Notice: ob_start(): failed to create buffer in %s on line 68
bool(false)
Array Array
( (
[0] => f )
[1] => C::g
[2] => C::g
[3] => C::h
)

View file

@ -21,13 +21,13 @@ var_dump(ob_get_level());
--EXPECTF-- --EXPECTF--
[callback:1]All of the following calls will fail to clean/remove the topmost buffer: [callback:1]All of the following calls will fail to clean/remove the topmost buffer:
Notice: ob_clean(): failed to delete buffer callback. in %s on line 11 Notice: ob_clean(): failed to delete buffer of callback (0) in %s on line 11
bool(false) bool(false)
Notice: ob_end_clean(): failed to delete buffer callback. in %s on line 12 Notice: ob_end_clean(): failed to discard buffer of callback (0) in %s on line 12
bool(false) bool(false)
Notice: ob_end_flush(): failed to delete buffer callback. in %s on line 13 Notice: ob_end_flush(): failed to send buffer of callback (0) in %s on line 13
bool(false) bool(false)
The OB nesting will still be 1 level deep: The OB nesting will still be 1 level deep:
int(1) int(1)

View file

@ -10,12 +10,13 @@ function callback($string) {
ob_start('callback', 0, false); ob_start('callback', 0, false);
echo "This call will fail to obtain the content, since it is also requesting a clean:\n"; echo "This call will obtain the content, but will not clean the buffer.";
$str = ob_get_clean(); $str = ob_get_clean();
var_dump($str); var_dump($str);
?> ?>
--EXPECTF-- --EXPECTF--
[callback:1]This call will fail to obtain the content, since it is also requesting a clean: [callback:1]This call will obtain the content, but will not clean the buffer.
Notice: ob_get_clean(): failed to discard buffer of callback (0) in %s on line 11
Notice: ob_get_clean(): failed to delete buffer callback. in %s on line 11 Notice: ob_get_clean(): failed to delete buffer of callback (0) in %s on line 11
bool(false) string(65) "This call will obtain the content, but will not clean the buffer."

View file

@ -10,12 +10,13 @@ function callback($string) {
ob_start('callback', 0, false); ob_start('callback', 0, false);
echo "This call will fail to flush and fail to obtain the content:\n"; echo "This call will obtain the content, but will not flush the buffer.";
$str = ob_get_flush(); $str = ob_get_flush();
var_dump($str); var_dump($str);
?> ?>
--EXPECTF-- --EXPECTF--
[callback:1]This call will fail to flush and fail to obtain the content: [callback:1]This call will obtain the content, but will not flush the buffer.
Notice: ob_get_flush(): failed to send buffer of callback (0) in %s on line 11
Notice: ob_get_flush(): failed to delete buffer callback. in %s on line 11 Notice: ob_get_flush(): failed to delete buffer of callback (0) in %s on line 11
bool(false) string(65) "This call will obtain the content, but will not flush the buffer."

View file

@ -17,9 +17,9 @@ var_dump(ob_get_contents());
?> ?>
--EXPECTF-- --EXPECTF--
[callback:1]Attempt to flush unerasable buffer - should fail... [callback:1]Attempt to flush unerasable buffer - should fail...
Notice: ob_flush(): failed to flush buffer callback. in %s on line 11 Notice: ob_flush(): failed to flush buffer of callback (0) in %s on line 11
bool(false) bool(false)
string(%d) "Attempt to flush unerasable buffer - should fail... string(%d) "Attempt to flush unerasable buffer - should fail...
Notice: ob_flush(): failed to flush buffer callback. in %s on line 11 Notice: ob_flush(): failed to flush buffer of callback (0) in %s on line 11
bool(false) bool(false)
" "

View file

@ -30,19 +30,22 @@ var_dump(ob_start("justPrint", 0, "this should be a bool"));
?> ?>
--EXPECTF-- --EXPECTF--
- Too many arguments - Too many arguments
Warning: ob_start() expects at most 3 parameters, 4 given in %s on line 17 Warning: ob_start() expects at most 3 parameters, 4 given in %s on line 17
NULL bool(false)
- Arg 1 wrong type - Arg 1 wrong type
bool(true)
Notice: ob_start(): failed to create buffer in %s on line 20
bool(false)
- Arg 2 wrong type - Arg 2 wrong type
Warning: ob_start() expects parameter 2 to be long, string given in %s on line 23 Warning: ob_start() expects parameter 2 to be long, string given in %s on line 23
NULL bool(false)
- Arg 3 wrong type - Arg 3 wrong type
bool(true)
Warning: ob_start() expects parameter 3 to be long, string given in %s on line 26
bool(false)

View file

@ -20,8 +20,15 @@ var_dump(ob_start("no"));
echo "done" echo "done"
?> ?>
--EXPECTF-- --EXPECTF--
Notice: ob_start(): failed to create buffer in %s on line 13
bool(false) bool(false)
Notice: ob_start(): failed to create buffer in %s on line 14
bool(false) bool(false)
Notice: ob_start(): failed to create buffer in %s on line 15
bool(false) bool(false)
Notice: ob_start(): failed to create buffer in %s on line 16
bool(false) bool(false)
done done

View file

@ -15,4 +15,6 @@ var_dump(ob_start(array($c)));
echo "done" echo "done"
?> ?>
--EXPECTF-- --EXPECTF--
Catchable fatal error: Object of class C could not be converted to string in %s on line 11 Notice: ob_start(): failed to create buffer in %s on line 11
bool(false)
done

View file

@ -15,4 +15,6 @@ var_dump(ob_start(array($c, 'f')));
echo "done" echo "done"
?> ?>
--EXPECTF-- --EXPECTF--
Catchable fatal error: Object of class C could not be converted to string in %s on line 11 Notice: ob_start(): failed to create buffer in %s on line 11
bool(false)
done