Skip to content

Commit 11d24c1

Browse files
committed
* 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.
1 parent 27299b7 commit 11d24c1

File tree

85 files changed

+3410
-2550
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3410
-2550
lines changed

README.NEW-OUTPUT-API

+426
Large diffs are not rendered by default.

ext/iconv/iconv.c

+67-62
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,6 @@ ZEND_BEGIN_ARG_INFO(arginfo_iconv, 0)
112112
ZEND_ARG_INFO(0, str)
113113
ZEND_END_ARG_INFO()
114114

115-
ZEND_BEGIN_ARG_INFO(arginfo_ob_iconv_handler, 0)
116-
ZEND_ARG_INFO(0, contents)
117-
ZEND_ARG_INFO(0, status)
118-
ZEND_END_ARG_INFO()
119-
120115
ZEND_BEGIN_ARG_INFO(arginfo_iconv_set_encoding, 0)
121116
ZEND_ARG_INFO(0, type)
122117
ZEND_ARG_INFO(0, charset)
@@ -132,7 +127,6 @@ ZEND_END_ARG_INFO()
132127
*/
133128
const zend_function_entry iconv_functions[] = {
134129
PHP_RAW_NAMED_FE(iconv,php_if_iconv, arginfo_iconv)
135-
PHP_FE(ob_iconv_handler, arginfo_ob_iconv_handler)
136130
PHP_FE(iconv_get_encoding, arginfo_iconv_get_encoding)
137131
PHP_FE(iconv_set_encoding, arginfo_iconv_set_encoding)
138132
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
214208

215209
static php_iconv_err_t php_iconv_stream_filter_register_factory(TSRMLS_D);
216210
static php_iconv_err_t php_iconv_stream_filter_unregister_factory(TSRMLS_D);
211+
212+
static int php_iconv_output_conflict(const char *handler_name, size_t handler_name_len TSRMLS_DC);
213+
static php_output_handler *php_iconv_output_handler_init(const char *name, size_t name_len, size_t chunk_size, int flags TSRMLS_DC);
214+
static int php_iconv_output_handler(void **nothing, php_output_context *output_context);
217215
/* }}} */
218216

219217
/* {{{ static globals */
@@ -278,6 +276,9 @@ PHP_MINIT_FUNCTION(miconv)
278276
return FAILURE;
279277
}
280278

279+
php_output_handler_alias_register(ZEND_STRL("ob_iconv_handler"), php_iconv_output_handler_init TSRMLS_CC);
280+
php_output_handler_conflict_register(ZEND_STRL("ob_iconv_handler"), php_iconv_output_conflict TSRMLS_CC);
281+
281282
return SUCCESS;
282283
}
283284
/* }}} */
@@ -312,6 +313,62 @@ PHP_MINFO_FUNCTION(miconv)
312313
}
313314
/* }}} */
314315

316+
static int php_iconv_output_conflict(const char *handler_name, size_t handler_name_len TSRMLS_DC)
317+
{
318+
if (php_output_get_level(TSRMLS_C)) {
319+
if (php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("ob_iconv_handler") TSRMLS_CC)
320+
|| php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("mb_output_handler") TSRMLS_CC)) {
321+
return FAILURE;
322+
}
323+
}
324+
return SUCCESS;
325+
}
326+
327+
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)
328+
{
329+
return php_output_handler_create_internal(handler_name, handler_name_len, php_iconv_output_handler, chunk_size, flags TSRMLS_CC);
330+
}
331+
332+
static int php_iconv_output_handler(void **nothing, php_output_context *output_context)
333+
{
334+
char *s, *content_type, *mimetype = NULL;
335+
int output_status, mimetype_len = 0;
336+
PHP_OUTPUT_TSRMLS(output_context);
337+
338+
if (output_context->op & PHP_OUTPUT_HANDLER_START) {
339+
output_status = php_output_get_status(TSRMLS_C);
340+
if (output_status & PHP_OUTPUT_SENT) {
341+
return FAILURE;
342+
}
343+
344+
if (SG(sapi_headers).mimetype && !strncasecmp(SG(sapi_headers).mimetype, "text/", 5)) {
345+
if ((s = strchr(SG(sapi_headers).mimetype,';')) == NULL){
346+
mimetype = SG(sapi_headers).mimetype;
347+
} else {
348+
mimetype = SG(sapi_headers).mimetype;
349+
mimetype_len = s - SG(sapi_headers).mimetype;
350+
}
351+
} else if (SG(sapi_headers).send_default_content_type) {
352+
mimetype = SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE;
353+
}
354+
355+
if (mimetype != NULL && !(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) {
356+
int len = spprintf(&content_type, 0, "Content-Type: %.*s; charset=%s", mimetype_len?mimetype_len:strlen(mimetype), mimetype, ICONVG(output_encoding));
357+
if (content_type && SUCCESS == sapi_add_header(content_type, len, 0)) {
358+
SG(sapi_headers).send_default_content_type = 0;
359+
php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
360+
}
361+
}
362+
}
363+
364+
if (output_context->in.used) {
365+
output_context->out.free = 1;
366+
_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);
367+
}
368+
369+
return SUCCESS;
370+
}
371+
315372
/* {{{ _php_iconv_appendl() */
316373
static php_iconv_err_t _php_iconv_appendl(smart_str *d, const char *s, size_t l, iconv_t cd)
317374
{
@@ -1131,7 +1188,7 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn
11311188
goto out;
11321189
}
11331190
break;
1134-
1191+
11351192
default:
11361193
err = PHP_ICONV_ERR_UNKNOWN;
11371194
goto out;
@@ -1725,7 +1782,7 @@ static php_iconv_err_t _php_iconv_mime_decode(smart_str *pretval, const char *st
17251782
break;
17261783

17271784
case '\n':
1728-
scan_stat = 8;
1785+
scan_stat = 8;
17291786
break;
17301787

17311788
case '=': /* first letter of an encoded chunk */
@@ -2308,58 +2365,6 @@ PHP_NAMED_FUNCTION(php_if_iconv)
23082365
}
23092366
/* }}} */
23102367

2311-
/* {{{ proto string ob_iconv_handler(string contents, int status)
2312-
Returns str in output buffer converted to the iconv.output_encoding character set */
2313-
PHP_FUNCTION(ob_iconv_handler)
2314-
{
2315-
char *out_buffer, *content_type, *mimetype = NULL, *s;
2316-
zval *zv_string;
2317-
size_t out_len;
2318-
int mimetype_alloced = 0;
2319-
long status;
2320-
2321-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &zv_string, &status) == FAILURE)
2322-
return;
2323-
2324-
convert_to_string(zv_string);
2325-
2326-
if (SG(sapi_headers).mimetype &&
2327-
strncasecmp(SG(sapi_headers).mimetype, "text/", 5) == 0) {
2328-
if ((s = strchr(SG(sapi_headers).mimetype,';')) == NULL){
2329-
mimetype = SG(sapi_headers).mimetype;
2330-
} else {
2331-
mimetype = estrndup(SG(sapi_headers).mimetype, s-SG(sapi_headers).mimetype);
2332-
mimetype_alloced = 1;
2333-
}
2334-
} else if (SG(sapi_headers).send_default_content_type) {
2335-
mimetype =(SG(default_mimetype) ? SG(default_mimetype) : SAPI_DEFAULT_MIMETYPE);
2336-
}
2337-
if (mimetype != NULL) {
2338-
php_iconv_err_t err = php_iconv_string(Z_STRVAL_P(zv_string),
2339-
Z_STRLEN_P(zv_string), &out_buffer, &out_len,
2340-
ICONVG(output_encoding), ICONVG(internal_encoding));
2341-
_php_iconv_show_error(err, ICONVG(output_encoding), ICONVG(internal_encoding) TSRMLS_CC);
2342-
if (out_buffer != NULL) {
2343-
int len = spprintf(&content_type, 0, "Content-Type:%s; charset=%s", mimetype, ICONVG(output_encoding));
2344-
if (content_type && sapi_add_header(content_type, len, 0) != FAILURE) {
2345-
SG(sapi_headers).send_default_content_type = 0;
2346-
}
2347-
if (mimetype_alloced) {
2348-
efree(mimetype);
2349-
}
2350-
RETURN_STRINGL(out_buffer, out_len, 0);
2351-
}
2352-
if (mimetype_alloced) {
2353-
efree(mimetype);
2354-
}
2355-
}
2356-
2357-
zval_dtor(return_value);
2358-
*return_value = *zv_string;
2359-
zval_copy_ctor(return_value);
2360-
}
2361-
/* }}} */
2362-
23632368
/* {{{ proto bool iconv_set_encoding(string type, string charset)
23642369
Sets internal encoding and output encoding for ob_iconv_handler() */
23652370
PHP_FUNCTION(iconv_set_encoding)
@@ -2488,7 +2493,7 @@ static int php_iconv_stream_filter_append_bucket(
24882493
char *pd, *pt;
24892494
size_t ocnt, prev_ocnt, icnt, tcnt;
24902495
size_t initial_out_buf_size;
2491-
2496+
24922497
if (ps == NULL) {
24932498
initial_out_buf_size = 64;
24942499
icnt = 1;
@@ -2784,7 +2789,7 @@ static php_stream_filter *php_iconv_stream_filter_factory_create(const char *nam
27842789
pefree(inst, persistent);
27852790
}
27862791

2787-
return retval;
2792+
return retval;
27882793
}
27892794
/* }}} */
27902795

ext/session/session.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -1093,8 +1093,8 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
10931093
if (PS(cache_limiter)[0] == '\0') return 0;
10941094

10951095
if (SG(headers_sent)) {
1096-
char *output_start_filename = php_get_output_start_filename(TSRMLS_C);
1097-
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
1096+
char *output_start_filename = php_output_get_start_filename(TSRMLS_C);
1097+
int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);
10981098

10991099
if (output_start_filename) {
11001100
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) /* {{{ */
11331133
char *e_session_name, *e_id;
11341134

11351135
if (SG(headers_sent)) {
1136-
char *output_start_filename = php_get_output_start_filename(TSRMLS_C);
1137-
int output_start_lineno = php_get_output_start_lineno(TSRMLS_C);
1136+
char *output_start_filename = php_output_get_start_filename(TSRMLS_C);
1137+
int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);
11381138

11391139
if (output_start_filename) {
11401140
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);

0 commit comments

Comments
 (0)