From: Michael Wallner Date: Mon, 25 Sep 2006 10:45:41 +0000 (+0000) Subject: - fix segv with http.send.deflate.start_auto=1 and http_send_*() X-Git-Tag: RELEASE_1_3_1~10 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=13e641e4455b1f86520de7c6390b2b7659d65e54 - fix segv with http.send.deflate.start_auto=1 and http_send_*() --- diff --git a/http_encoding_api.c b/http_encoding_api.c index 06a175f..1975295 100644 --- a/http_encoding_api.c +++ b/http_encoding_api.c @@ -163,61 +163,57 @@ PHP_HTTP_API int _http_encoding_response_start(size_t content_length TSRMLS_DC) if ( php_ob_handler_used("ob_gzhandler" TSRMLS_CC) || php_ob_handler_used("zlib output compression" TSRMLS_CC)) { HTTP_G->send.deflate.encoding = 0; - } else { - if (!HTTP_G->send.deflate.encoding) { - /* emit a content-length header */ - if (content_length) { - char cl_header_str[128]; - size_t cl_header_len; - cl_header_len = snprintf(cl_header_str, lenof(cl_header_str), "Content-Length: %zu", content_length); - http_send_header_string_ex(cl_header_str, cl_header_len, 1); - } - } else { -#ifndef HTTP_HAVE_ZLIB - HTTP_G->send.deflate.encoding = 0; - php_start_ob_buffer_named("ob_gzhandler", 0, 0 TSRMLS_CC); -#else - HashTable *selected; - zval zsupported; - - INIT_PZVAL(&zsupported); - array_init(&zsupported); - add_next_index_stringl(&zsupported, "gzip", lenof("gzip"), 1); - add_next_index_stringl(&zsupported, "x-gzip", lenof("x-gzip"), 1); - add_next_index_stringl(&zsupported, "deflate", lenof("deflate"), 1); - - HTTP_G->send.deflate.encoding = 0; + } else if (HTTP_G->send.deflate.encoding) { + HTTP_G->send.deflate.encoding = 0; +#ifdef HTTP_HAVE_ZLIB + HashTable *selected; + zval zsupported; + + INIT_PZVAL(&zsupported); + array_init(&zsupported); + add_next_index_stringl(&zsupported, "gzip", lenof("gzip"), 1); + add_next_index_stringl(&zsupported, "x-gzip", lenof("x-gzip"), 1); + add_next_index_stringl(&zsupported, "deflate", lenof("deflate"), 1); + + if ((selected = http_negotiate_encoding(&zsupported))) { + STATUS hs = FAILURE; + char *encoding = NULL; + ulong idx; - if ((selected = http_negotiate_encoding(&zsupported))) { - STATUS hs = FAILURE; - char *encoding = NULL; - ulong idx; - - if (HASH_KEY_IS_STRING == zend_hash_get_current_key(selected, &encoding, &idx, 0) && encoding) { - if (!strcmp(encoding, "gzip") || !strcmp(encoding, "x-gzip")) { - if (SUCCESS == (hs = http_send_header_string("Content-Encoding: gzip"))) { - HTTP_G->send.deflate.encoding = HTTP_ENCODING_GZIP; - } - } else if (!strcmp(encoding, "deflate")) { - if (SUCCESS == (hs = http_send_header_string("Content-Encoding: deflate"))) { - HTTP_G->send.deflate.encoding = HTTP_ENCODING_DEFLATE; - } + if (HASH_KEY_IS_STRING == zend_hash_get_current_key(selected, &encoding, &idx, 0) && encoding) { + if (!strcmp(encoding, "gzip") || !strcmp(encoding, "x-gzip")) { + if (SUCCESS == (hs = http_send_header_string("Content-Encoding: gzip"))) { + HTTP_G->send.deflate.encoding = HTTP_ENCODING_GZIP; } - if (SUCCESS == hs) { - http_send_header_string("Vary: Accept-Encoding"); + } else if (!strcmp(encoding, "deflate")) { + if (SUCCESS == (hs = http_send_header_string("Content-Encoding: deflate"))) { + HTTP_G->send.deflate.encoding = HTTP_ENCODING_DEFLATE; } } - - zend_hash_destroy(selected); - FREE_HASHTABLE(selected); + if (SUCCESS == hs) { + http_send_header_string("Vary: Accept-Encoding"); + } } - zval_dtor(&zsupported); - return HTTP_G->send.deflate.encoding; -#endif + zend_hash_destroy(selected); + FREE_HASHTABLE(selected); + } + + zval_dtor(&zsupported); +#else + php_start_ob_buffer_named("ob_gzhandler", 0, 0 TSRMLS_CC); +#endif /* HTTP_HAVE_ZLIB */ + } else { + HTTP_G->send.deflate.encoding = 0; + if (content_length) { + /* emit a content-length header */ + char cl_header_str[128]; + size_t cl_header_len; + cl_header_len = snprintf(cl_header_str, lenof(cl_header_str), "Content-Length: %zu", content_length); + http_send_header_string_ex(cl_header_str, cl_header_len, 1); } } - return 0; + return HTTP_G->send.deflate.encoding; } /* }}} */ @@ -687,7 +683,9 @@ void _http_ob_deflatehandler(char *output, uint output_len, char **handled_outpu } if (HTTP_G->send.deflate.stream) { - http_encoding_deflate_stream_update((http_encoding_stream *) HTTP_G->send.deflate.stream, output, output_len, handled_output, handled_output_len); + if (output_len) { + http_encoding_deflate_stream_update((http_encoding_stream *) HTTP_G->send.deflate.stream, output, output_len, handled_output, handled_output_len); + } if (mode & PHP_OUTPUT_HANDLER_END) { char *remaining = NULL; @@ -724,7 +722,9 @@ void _http_ob_inflatehandler(char *output, uint output_len, char **handled_outpu } if (HTTP_G->send.inflate.stream) { - http_encoding_inflate_stream_update((http_encoding_stream *) HTTP_G->send.inflate.stream, output, output_len, handled_output, handled_output_len); + if (output_len) { + http_encoding_inflate_stream_update((http_encoding_stream *) HTTP_G->send.inflate.stream, output, output_len, handled_output, handled_output_len); + } if (mode & PHP_OUTPUT_HANDLER_END) { char *remaining = NULL; diff --git a/http_send_api.c b/http_send_api.c index 0c1fe57..2be92b6 100644 --- a/http_send_api.c +++ b/http_send_api.c @@ -65,7 +65,7 @@ static inline void _http_send_response_start(void **buffer, size_t content_lengt #define http_send_response_data_plain(b, d, dl) _http_send_response_data_plain((b), (d), (dl) TSRMLS_CC) static inline void _http_send_response_data_plain(void **buffer, const char *data, size_t data_len TSRMLS_DC) { - if (HTTP_G->send.deflate.encoding) { + if (HTTP_G->send.deflate.encoding && *(http_encoding_stream **) buffer) { #ifdef HTTP_HAVE_ZLIB char *encoded; size_t encoded_len; @@ -137,7 +137,7 @@ static inline void _http_send_response_data_fetch(void **buffer, const void *dat #define http_send_response_finish(b) _http_send_response_finish((b) TSRMLS_CC) static inline void _http_send_response_finish(void **buffer TSRMLS_DC) { - if (HTTP_G->send.deflate.encoding) { + if (HTTP_G->send.deflate.encoding && *(http_encoding_stream **) buffer) { #ifdef HTTP_HAVE_ZLIB char *encoded = NULL; size_t encoded_len = 0;