mirror of
https://github.com/php/php-src.git
synced 2025-08-16 22:18:50 +02:00
Fixed bug #21228 (broken check for ob_gzhandler).
Fixed a bug that made ob_start return incorrect return value.
This commit is contained in:
parent
67f0a6f6c0
commit
0acb52fc3b
3 changed files with 44 additions and 31 deletions
|
@ -54,6 +54,7 @@ PHP_FUNCTION(gzencode);
|
||||||
PHP_FUNCTION(ob_gzhandler);
|
PHP_FUNCTION(ob_gzhandler);
|
||||||
|
|
||||||
int php_enable_output_compression(int buffer_size TSRMLS_DC);
|
int php_enable_output_compression(int buffer_size TSRMLS_DC);
|
||||||
|
int php_ob_gzhandler_check(TSRMLS_DC);
|
||||||
|
|
||||||
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);
|
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_ops php_stream_gzio_ops;
|
||||||
|
|
|
@ -890,6 +890,34 @@ PHP_FUNCTION(gzencode)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ php_ob_gzhandler_check
|
||||||
|
*/
|
||||||
|
int php_ob_gzhandler_check(TSRMLS_DC)
|
||||||
|
{
|
||||||
|
/* check for wrong usages */
|
||||||
|
if (OG(ob_nesting_level>0)) {
|
||||||
|
if (php_ob_handler_used("ob_gzhandler" TSRMLS_CC)) {
|
||||||
|
php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler 'ob_gzhandler' cannot be used twice");
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
if (php_ob_handler_used("mb_output_handler" TSRMLS_CC)) {
|
||||||
|
php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler 'ob_gzhandler' cannot be used after 'mb_output_handler'");
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
if (php_ob_handler_used("URL-Rewriter" TSRMLS_CC)) {
|
||||||
|
php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler 'ob_gzhandler' cannot be used after 'URL-Rewriter'");
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
if (php_ob_init_conflict("ob_gzhandler", "zlib output compression" TSRMLS_CC)) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ proto string ob_gzhandler(string str, int mode)
|
/* {{{ proto string ob_gzhandler(string str, int mode)
|
||||||
Encode str based on accept-encoding setting - designed to be called from ob_start() */
|
Encode str based on accept-encoding setting - designed to be called from ob_start() */
|
||||||
PHP_FUNCTION(ob_gzhandler)
|
PHP_FUNCTION(ob_gzhandler)
|
||||||
|
@ -904,24 +932,6 @@ PHP_FUNCTION(ob_gzhandler)
|
||||||
ZEND_WRONG_PARAM_COUNT();
|
ZEND_WRONG_PARAM_COUNT();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for wrong usages */
|
|
||||||
if (OG(ob_nesting_level>1)) {
|
|
||||||
if (php_ob_handler_used("ob_gzhandler" TSRMLS_CC)) {
|
|
||||||
php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler 'ob_gzhandler' cannot be used twice");
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
if (php_ob_handler_used("mb_output_handler" TSRMLS_CC)) {
|
|
||||||
php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler 'ob_gzhandler' cannot be used after 'mb_output_handler'");
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
if (php_ob_handler_used("URL-Rewriter" TSRMLS_CC)) {
|
|
||||||
php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler 'ob_gzhandler' cannot be used after 'URL-Rewriter'");
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
if (php_ob_init_conflict("ob_gzhandler", "zlib output compression" TSRMLS_CC))
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ZLIBG(ob_gzhandler_status)==-1
|
if (ZLIBG(ob_gzhandler_status)==-1
|
||||||
|| zend_hash_find(&EG(symbol_table), "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), (void **) &data)==FAILURE
|
|| zend_hash_find(&EG(symbol_table), "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), (void **) &data)==FAILURE
|
||||||
|| Z_TYPE_PP(data)!=IS_ARRAY
|
|| Z_TYPE_PP(data)!=IS_ARRAY
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#include "ext/standard/head.h"
|
#include "ext/standard/head.h"
|
||||||
#include "ext/standard/basic_functions.h"
|
#include "ext/standard/basic_functions.h"
|
||||||
#include "ext/standard/url_scanner_ex.h"
|
#include "ext/standard/url_scanner_ex.h"
|
||||||
|
#ifdef HAVE_ZLIB
|
||||||
|
#include "ext/zlib/php_zlib.h"
|
||||||
|
#endif
|
||||||
#include "SAPI.h"
|
#include "SAPI.h"
|
||||||
|
|
||||||
#define OB_DEFAULT_HANDLER_NAME "default output handler"
|
#define OB_DEFAULT_HANDLER_NAME "default output handler"
|
||||||
|
@ -405,6 +408,11 @@ PHPAPI int php_ob_init_conflict(char *handler_new, char *handler_set TSRMLS_DC)
|
||||||
static int php_ob_init_named(uint initial_size, uint block_size, char *handler_name, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
|
static int php_ob_init_named(uint initial_size, uint block_size, char *handler_name, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
|
||||||
{
|
{
|
||||||
if (OG(ob_nesting_level)>0) {
|
if (OG(ob_nesting_level)>0) {
|
||||||
|
#ifdef HAVE_ZLIB
|
||||||
|
if (!strncmp(handler_name, "ob_gzhandler", sizeof("ob_gzhandler")) && php_ob_gzhandler_check(TSRMLS_CC)) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (OG(ob_nesting_level)==1) { /* initialize stack */
|
if (OG(ob_nesting_level)==1) { /* initialize stack */
|
||||||
zend_stack_init(&OG(ob_buffers));
|
zend_stack_init(&OG(ob_buffers));
|
||||||
}
|
}
|
||||||
|
@ -445,22 +453,20 @@ static zval* php_ob_handler_from_string(const char *handler_name TSRMLS_DC)
|
||||||
*/
|
*/
|
||||||
static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
|
static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
|
||||||
{
|
{
|
||||||
int res, result, len;
|
int result, len;
|
||||||
char *handler_name, *next_handler_name;
|
char *handler_name, *next_handler_name;
|
||||||
HashPosition pos;
|
HashPosition pos;
|
||||||
zval **tmp;
|
zval **tmp;
|
||||||
zval *handler_zval;
|
zval *handler_zval;
|
||||||
|
|
||||||
if (output_handler && output_handler->type == IS_STRING) {
|
if (output_handler && output_handler->type == IS_STRING) {
|
||||||
result = 0;
|
|
||||||
handler_name = Z_STRVAL_P(output_handler);
|
handler_name = Z_STRVAL_P(output_handler);
|
||||||
while ((next_handler_name=strchr(handler_name, ',')) != NULL) {
|
while ((next_handler_name=strchr(handler_name, ',')) != NULL) {
|
||||||
len = next_handler_name-handler_name;
|
len = next_handler_name-handler_name;
|
||||||
next_handler_name = estrndup(handler_name, len);
|
next_handler_name = estrndup(handler_name, len);
|
||||||
handler_zval = php_ob_handler_from_string(next_handler_name TSRMLS_CC);
|
handler_zval = php_ob_handler_from_string(next_handler_name TSRMLS_CC);
|
||||||
res = php_ob_init_named(initial_size, block_size, next_handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
|
result = php_ob_init_named(initial_size, block_size, next_handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
|
||||||
result &= res;
|
if (result != SUCCESS) {
|
||||||
if (!res==SUCCESS) {
|
|
||||||
zval_dtor(handler_zval);
|
zval_dtor(handler_zval);
|
||||||
FREE_ZVAL(handler_zval);
|
FREE_ZVAL(handler_zval);
|
||||||
}
|
}
|
||||||
|
@ -468,15 +474,12 @@ static int php_ob_init(uint initial_size, uint block_size, zval *output_handler,
|
||||||
efree(next_handler_name);
|
efree(next_handler_name);
|
||||||
}
|
}
|
||||||
handler_zval = php_ob_handler_from_string(handler_name TSRMLS_CC);
|
handler_zval = php_ob_handler_from_string(handler_name TSRMLS_CC);
|
||||||
res = php_ob_init_named(initial_size, block_size, handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
|
result = php_ob_init_named(initial_size, block_size, handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
|
||||||
result &= res;
|
if (result != SUCCESS) {
|
||||||
if (!res==SUCCESS) {
|
|
||||||
zval_dtor(handler_zval);
|
zval_dtor(handler_zval);
|
||||||
FREE_ZVAL(handler_zval);
|
FREE_ZVAL(handler_zval);
|
||||||
}
|
}
|
||||||
result = result ? SUCCESS : FAILURE;
|
|
||||||
} else if (output_handler && output_handler->type == IS_ARRAY) {
|
} else if (output_handler && output_handler->type == IS_ARRAY) {
|
||||||
result = 0;
|
|
||||||
/* do we have array(object,method) */
|
/* do we have array(object,method) */
|
||||||
if (zend_is_callable(output_handler, 1, &handler_name)) {
|
if (zend_is_callable(output_handler, 1, &handler_name)) {
|
||||||
SEPARATE_ZVAL(&output_handler);
|
SEPARATE_ZVAL(&output_handler);
|
||||||
|
@ -487,11 +490,10 @@ static int php_ob_init(uint initial_size, uint block_size, zval *output_handler,
|
||||||
/* init all array elements recursively */
|
/* init all array elements recursively */
|
||||||
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(output_handler), &pos);
|
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(output_handler), &pos);
|
||||||
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(output_handler), (void **)&tmp, &pos) == SUCCESS) {
|
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(output_handler), (void **)&tmp, &pos) == SUCCESS) {
|
||||||
result &= php_ob_init(initial_size, block_size, *tmp, chunk_size, erase TSRMLS_CC);
|
result = php_ob_init(initial_size, block_size, *tmp, chunk_size, erase TSRMLS_CC);
|
||||||
zend_hash_move_forward_ex(Z_ARRVAL_P(output_handler), &pos);
|
zend_hash_move_forward_ex(Z_ARRVAL_P(output_handler), &pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = result ? SUCCESS : FAILURE;
|
|
||||||
} else if (output_handler && output_handler->type == IS_OBJECT) {
|
} else if (output_handler && output_handler->type == IS_OBJECT) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "No method name given: use ob_start(array($object,'method')) to specify instance $object and the name of a method of class %s to use as output handler", Z_OBJCE_P(output_handler)->name);
|
php_error_docref(NULL TSRMLS_CC, E_ERROR, "No method name given: use ob_start(array($object,'method')) to specify instance $object and the name of a method of class %s to use as output handler", Z_OBJCE_P(output_handler)->name);
|
||||||
result = FAILURE;
|
result = FAILURE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue