PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/zlib - zlib.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 475 589 80.6 %
Date: 2015-05-21 Functions: 41 42 97.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2015 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
      16             :    |          Stefan Röhrich <sr@linux.de>                                |
      17             :    |          Zeev Suraski <zeev@zend.com>                                |
      18             :    |          Jade Nicoletti <nicoletti@nns.ch>                           |
      19             :    |          Michael Wallner <mike@php.net>                              |
      20             :    +----------------------------------------------------------------------+
      21             :  */
      22             : 
      23             : /* $Id$ */
      24             : 
      25             : #ifdef HAVE_CONFIG_H
      26             : #include "config.h"
      27             : #endif
      28             : 
      29             : #include "php.h"
      30             : #include "SAPI.h"
      31             : #include "php_ini.h"
      32             : #include "ext/standard/info.h"
      33             : #include "ext/standard/file.h"
      34             : #include "ext/standard/php_string.h"
      35             : #include "php_zlib.h"
      36             : 
      37             : /*
      38             :  * zlib include files can define the following preprocessor defines which rename
      39             :  * the corresponding PHP functions to gzopen64, gzseek64 and gztell64 and thereby
      40             :  * breaking some software, most notably PEAR's Archive_Tar, which halts execution
      41             :  * without error message on gzip compressed archivesa.
      42             :  *
      43             :  * This only seems to happen on 32bit systems with large file support.
      44             :  */
      45             : #undef gzopen
      46             : #undef gzseek
      47             : #undef gztell
      48             : 
      49             : int le_deflate;
      50             : int le_inflate;
      51             : 
      52             : ZEND_DECLARE_MODULE_GLOBALS(zlib);
      53             : 
      54             : /* {{{ Memory management wrappers */
      55             : 
      56        1164 : static voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size)
      57             : {
      58        1164 :         return (voidpf)safe_emalloc(items, size, 0);
      59             : }
      60             : 
      61        1164 : static void php_zlib_free(voidpf opaque, voidpf address)
      62             : {
      63        1164 :         efree((void*)address);
      64        1164 : }
      65             : /* }}} */
      66             : 
      67             : /* {{{ Incremental deflate/inflate resource destructors */
      68             : 
      69          40 : void deflate_rsrc_dtor(zend_resource *res)
      70             : {
      71          40 :         z_stream *ctx = zend_fetch_resource(res, NULL, le_deflate);
      72          40 :         deflateEnd(ctx);
      73          40 :         efree(ctx);
      74          40 : }
      75             : 
      76          49 : void inflate_rsrc_dtor(zend_resource *res)
      77             : {
      78          49 :         z_stream *ctx = zend_fetch_resource(res, NULL, le_inflate);
      79          49 :         if (((php_zlib_context *) ctx)->inflateDict) {
      80           0 :                 efree(((php_zlib_context *) ctx)->inflateDict);
      81             :         }
      82          49 :         inflateEnd(ctx);
      83          49 :         efree(ctx);
      84          49 : }
      85             : 
      86             : /* }}} */
      87             : 
      88             : /* {{{ php_zlib_output_conflict_check() */
      89          20 : static int php_zlib_output_conflict_check(const char *handler_name, size_t handler_name_len)
      90             : {
      91          20 :         if (php_output_get_level() > 0) {
      92           5 :                 if (php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME))
      93           2 :                 ||      php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("ob_gzhandler"))
      94           1 :                 ||  php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("mb_output_handler"))
      95           2 :                 ||      php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("URL-Rewriter"))) {
      96           1 :                         return FAILURE;
      97             :                 }
      98             :         }
      99          19 :         return SUCCESS;
     100             : }
     101             : /* }}} */
     102             : 
     103             : /* {{{ php_zlib_output_encoding() */
     104          36 : static int php_zlib_output_encoding(void)
     105             : {
     106             :         zval *enc;
     107             : 
     108          36 :         if (!ZLIBG(compression_coding)) {
     109          50 :                 if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
     110          25 :                         (enc = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING") - 1))) {
     111          16 :                         convert_to_string(enc);
     112          16 :                         if (strstr(Z_STRVAL_P(enc), "gzip")) {
     113          16 :                                 ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_GZIP;
     114           0 :                         } else if (strstr(Z_STRVAL_P(enc), "deflate")) {
     115           0 :                                 ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_DEFLATE;
     116             :                         }
     117             :                 }
     118             :         }
     119          36 :         return ZLIBG(compression_coding);
     120             : }
     121             : /* }}} */
     122             : 
     123             : /* {{{ php_zlib_output_handler_ex() */
     124          16 : static int php_zlib_output_handler_ex(php_zlib_context *ctx, php_output_context *output_context)
     125             : {
     126          16 :         int flags = Z_SYNC_FLUSH;
     127             :         PHP_OUTPUT_TSRMLS(output_context);
     128             : 
     129          16 :         if (output_context->op & PHP_OUTPUT_HANDLER_START) {
     130             :                 /* start up */
     131          16 :                 if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) {
     132           0 :                         return FAILURE;
     133             :                 }
     134             :         }
     135             : 
     136          16 :         if (output_context->op & PHP_OUTPUT_HANDLER_CLEAN) {
     137             :                 /* free buffers */
     138           0 :                 deflateEnd(&ctx->Z);
     139             : 
     140           0 :                 if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
     141             :                         /* discard */
     142           0 :                         return SUCCESS;
     143             :                 } else {
     144             :                         /* restart */
     145           0 :                         if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) {
     146           0 :                                 return FAILURE;
     147             :                         }
     148           0 :                         ctx->buffer.used = 0;
     149             :                 }
     150             :         } else {
     151          16 :                 if (output_context->in.used) {
     152             :                         /* append input */
     153          10 :                         if (ctx->buffer.free < output_context->in.used) {
     154          10 :                                 if (!(ctx->buffer.aptr = erealloc_recoverable(ctx->buffer.data, ctx->buffer.used + ctx->buffer.free + output_context->in.used))) {
     155           0 :                                         deflateEnd(&ctx->Z);
     156           0 :                                         return FAILURE;
     157             :                                 }
     158          10 :                                 ctx->buffer.data = ctx->buffer.aptr;
     159          10 :                                 ctx->buffer.free += output_context->in.used;
     160             :                         }
     161          10 :                         memcpy(ctx->buffer.data + ctx->buffer.used, output_context->in.data, output_context->in.used);
     162          10 :                         ctx->buffer.free -= output_context->in.used;
     163          10 :                         ctx->buffer.used += output_context->in.used;
     164             :                 }
     165          16 :                 output_context->out.size = PHP_ZLIB_BUFFER_SIZE_GUESS(output_context->in.used);
     166          16 :                 output_context->out.data = emalloc(output_context->out.size);
     167          16 :                 output_context->out.free = 1;
     168          16 :                 output_context->out.used = 0;
     169             : 
     170          16 :                 ctx->Z.avail_in = ctx->buffer.used;
     171          16 :                 ctx->Z.next_in = (Bytef *) ctx->buffer.data;
     172          16 :                 ctx->Z.avail_out = output_context->out.size;
     173          16 :                 ctx->Z.next_out = (Bytef *) output_context->out.data;
     174             : 
     175          16 :                 if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
     176          16 :                         flags = Z_FINISH;
     177           0 :                 } else if (output_context->op & PHP_OUTPUT_HANDLER_FLUSH) {
     178           0 :                         flags = Z_FULL_FLUSH;
     179             :                 }
     180             : 
     181          16 :                 switch (deflate(&ctx->Z, flags)) {
     182             :                         case Z_OK:
     183           0 :                                 if (flags == Z_FINISH) {
     184           0 :                                         deflateEnd(&ctx->Z);
     185           0 :                                         return FAILURE;
     186             :                                 }
     187             :                         case Z_STREAM_END:
     188          16 :                                 if (ctx->Z.avail_in) {
     189           0 :                                         memmove(ctx->buffer.data, ctx->buffer.data + ctx->buffer.used - ctx->Z.avail_in, ctx->Z.avail_in);
     190             :                                 }
     191          16 :                                 ctx->buffer.free += ctx->buffer.used - ctx->Z.avail_in;
     192          16 :                                 ctx->buffer.used = ctx->Z.avail_in;
     193          16 :                                 output_context->out.used = output_context->out.size - ctx->Z.avail_out;
     194          16 :                                 break;
     195             :                         default:
     196           0 :                                 deflateEnd(&ctx->Z);
     197           0 :                                 return FAILURE;
     198             :                 }
     199             : 
     200          16 :                 if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
     201          16 :                         deflateEnd(&ctx->Z);
     202             :                 }
     203             :         }
     204             : 
     205          16 :         return SUCCESS;
     206             : }
     207             : /* }}} */
     208             : 
     209             : /* {{{ php_zlib_output_handler() */
     210          20 : static int php_zlib_output_handler(void **handler_context, php_output_context *output_context)
     211             : {
     212          20 :         php_zlib_context *ctx = *(php_zlib_context **) handler_context;
     213             :         PHP_OUTPUT_TSRMLS(output_context);
     214             : 
     215          20 :         if (!php_zlib_output_encoding()) {
     216             :                 /* "Vary: Accept-Encoding" header sent along uncompressed content breaks caching in MSIE,
     217             :                         so let's just send it with successfully compressed content or unless the complete
     218             :                         buffer gets discarded, see http://bugs.php.net/40325;
     219             : 
     220             :                         Test as follows:
     221             :                         +Vary: $ HTTP_ACCEPT_ENCODING=gzip ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n";'
     222             :                         +Vary: $ HTTP_ACCEPT_ENCODING= ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n";'
     223             :                         -Vary: $ HTTP_ACCEPT_ENCODING=gzip ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n"; ob_end_clean();'
     224             :                         -Vary: $ HTTP_ACCEPT_ENCODING= ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n"; ob_end_clean();'
     225             :                 */
     226           7 :                 if ((output_context->op & PHP_OUTPUT_HANDLER_START)
     227           3 :                 &&      (output_context->op != (PHP_OUTPUT_HANDLER_START|PHP_OUTPUT_HANDLER_CLEAN|PHP_OUTPUT_HANDLER_FINAL))
     228             :                 ) {
     229           3 :                         sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 0);
     230             :                 }
     231           4 :                 return FAILURE;
     232             :         }
     233             : 
     234          16 :         if (SUCCESS != php_zlib_output_handler_ex(ctx, output_context)) {
     235           0 :                 return FAILURE;
     236             :         }
     237             : 
     238          16 :         if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) {
     239             :                 int flags;
     240             : 
     241          16 :                 if (SUCCESS == php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS, &flags)) {
     242             :                         /* only run this once */
     243          16 :                         if (!(flags & PHP_OUTPUT_HANDLER_STARTED)) {
     244          16 :                                 if (SG(headers_sent) || !ZLIBG(output_compression)) {
     245           7 :                                         deflateEnd(&ctx->Z);
     246           7 :                                         return FAILURE;
     247             :                                 }
     248           9 :                                 switch (ZLIBG(compression_coding)) {
     249             :                                         case PHP_ZLIB_ENCODING_GZIP:
     250           9 :                                                 sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1);
     251           9 :                                                 break;
     252             :                                         case PHP_ZLIB_ENCODING_DEFLATE:
     253           0 :                                                 sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1);
     254           0 :                                                 break;
     255             :                                         default:
     256           0 :                                                 deflateEnd(&ctx->Z);
     257           0 :                                                 return FAILURE;
     258             :                                 }
     259           9 :                                 sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 0);
     260           9 :                                 php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL);
     261             :                         }
     262             :                 }
     263             :         }
     264             : 
     265           9 :         return SUCCESS;
     266             : }
     267             : /* }}} */
     268             : 
     269             : /* {{{ php_zlib_output_handler_context_init() */
     270          20 : static php_zlib_context *php_zlib_output_handler_context_init(void)
     271             : {
     272          20 :         php_zlib_context *ctx = (php_zlib_context *) ecalloc(1, sizeof(php_zlib_context));
     273          20 :         ctx->Z.zalloc = php_zlib_alloc;
     274          20 :         ctx->Z.zfree = php_zlib_free;
     275          20 :         return ctx;
     276             : }
     277             : /* }}} */
     278             : 
     279             : /* {{{ php_zlib_output_handler_context_dtor() */
     280          20 : static void php_zlib_output_handler_context_dtor(void *opaq)
     281             : {
     282          20 :         php_zlib_context *ctx = (php_zlib_context *) opaq;
     283             : 
     284          20 :         if (ctx) {
     285          20 :                 if (ctx->buffer.data) {
     286          10 :                         efree(ctx->buffer.data);
     287             :                 }
     288          20 :                 efree(ctx);
     289             :         }
     290          20 : }
     291             : /* }}} */
     292             : 
     293             : /* {{{ php_zlib_output_handler_init() */
     294          20 : static php_output_handler *php_zlib_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags)
     295             : {
     296          20 :         php_output_handler *h = NULL;
     297             : 
     298          20 :         if (!ZLIBG(output_compression)) {
     299           8 :                 ZLIBG(output_compression) = chunk_size ? chunk_size : PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
     300             :         }
     301             : 
     302          20 :     ZLIBG(handler_registered) = 1;
     303             : 
     304          20 :         if ((h = php_output_handler_create_internal(handler_name, handler_name_len, php_zlib_output_handler, chunk_size, flags))) {
     305          20 :                 php_output_handler_set_context(h, php_zlib_output_handler_context_init(), php_zlib_output_handler_context_dtor);
     306             :         }
     307             : 
     308          20 :         return h;
     309             : }
     310             : /* }}} */
     311             : 
     312             : /* {{{ php_zlib_output_compression_start() */
     313       20873 : static void php_zlib_output_compression_start(void)
     314             : {
     315             :         zval zoh;
     316             :         php_output_handler *h;
     317             : 
     318       20873 :         switch (ZLIBG(output_compression)) {
     319             :                 case 0:
     320       20858 :                         break;
     321             :                 case 1:
     322          14 :                         ZLIBG(output_compression) = PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
     323             :                         /* break omitted intentionally */
     324             :                 default:
     325          37 :                         if (    php_zlib_output_encoding() &&
     326          11 :                                         (h = php_zlib_output_handler_init(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS)) &&
     327          11 :                                         (SUCCESS == php_output_handler_start(h))) {
     328          11 :                                 if (ZLIBG(output_handler) && *ZLIBG(output_handler)) {
     329           0 :                                         ZVAL_STRING(&zoh, ZLIBG(output_handler));
     330           0 :                                         php_output_start_user(&zoh, ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS);
     331           0 :                                         zval_ptr_dtor(&zoh);
     332             :                                 }
     333             :                         }
     334             :                         break;
     335             :         }
     336       20873 : }
     337             : /* }}} */
     338             : 
     339             : /* {{{ php_zlib_encode() */
     340         124 : static zend_string *php_zlib_encode(const char *in_buf, size_t in_len, int encoding, int level)
     341             : {
     342             :         int status;
     343             :         z_stream Z;
     344             :         zend_string *out;
     345             : 
     346         124 :         memset(&Z, 0, sizeof(z_stream));
     347         124 :         Z.zalloc = php_zlib_alloc;
     348         124 :         Z.zfree = php_zlib_free;
     349             : 
     350         124 :         if (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, encoding, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) {
     351         248 :                 out = zend_string_alloc(PHP_ZLIB_BUFFER_SIZE_GUESS(in_len), 0);
     352             : 
     353         124 :                 Z.next_in = (Bytef *) in_buf;
     354         124 :                 Z.next_out = (Bytef *) out->val;
     355         124 :                 Z.avail_in = in_len;
     356         124 :                 Z.avail_out = out->len;
     357             : 
     358         124 :                 status = deflate(&Z, Z_FINISH);
     359         124 :                 deflateEnd(&Z);
     360             : 
     361         124 :                 if (Z_STREAM_END == status) {
     362             :                         /* size buffer down to actual length */
     363         248 :                         out = zend_string_truncate(out, Z.total_out, 0);
     364         124 :                         out->val[out->len] = '\0';
     365         124 :                         return out;
     366             :                 } else {
     367             :                         zend_string_free(out);
     368             :                 }
     369             :         }
     370             : 
     371           0 :         php_error_docref(NULL, E_WARNING, "%s", zError(status));
     372           0 :         return NULL;
     373             : }
     374             : /* }}} */
     375             : 
     376             : /* {{{ php_zlib_inflate_rounds() */
     377         130 : static inline int php_zlib_inflate_rounds(z_stream *Z, size_t max, char **buf, size_t *len)
     378             : {
     379         130 :         int status, round = 0;
     380         130 :         php_zlib_buffer buffer = {NULL, NULL, 0, 0, 0};
     381             : 
     382         130 :         *buf = NULL;
     383         130 :         *len = 0;
     384             : 
     385         130 :         buffer.size = (max && (max < Z->avail_in)) ? max : Z->avail_in;
     386             : 
     387             :         do {
     388         548 :                 if ((max && (max <= buffer.used)) || !(buffer.aptr = erealloc_recoverable(buffer.data, buffer.size))) {
     389           2 :                         status = Z_MEM_ERROR;
     390             :                 } else {
     391         544 :                         buffer.data = buffer.aptr;
     392         544 :                         Z->avail_out = buffer.free = buffer.size - buffer.used;
     393         544 :                         Z->next_out = (Bytef *) buffer.data + buffer.used;
     394             : #if 0
     395             :                         fprintf(stderr, "\n%3d: %3d PRIOR: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
     396             : #endif
     397         544 :                         status = inflate(Z, Z_NO_FLUSH);
     398             : 
     399         544 :                         buffer.used += buffer.free - Z->avail_out;
     400         544 :                         buffer.free = Z->avail_out;
     401             : #if 0
     402             :                         fprintf(stderr, "%3d: %3d AFTER: size=%7lu,\tfree=%7lu,\tused=%7lu,\tavail_in=%7lu,\tavail_out=%7lu\n", round, status, buffer.size, buffer.free, buffer.used, Z->avail_in, Z->avail_out);
     403             : #endif
     404         544 :                         buffer.size += (buffer.size >> 3) + 1;
     405             :                 }
     406         546 :         } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < 100);
     407             : 
     408         130 :         if (status == Z_STREAM_END) {
     409         108 :                 buffer.data = erealloc(buffer.data, buffer.used + 1);
     410         108 :                 buffer.data[buffer.used] = '\0';
     411         108 :                 *buf = buffer.data;
     412         108 :                 *len = buffer.used;
     413             :         } else {
     414          22 :                 if (buffer.data) {
     415          22 :                         efree(buffer.data);
     416             :                 }
     417             :                 /* HACK: See zlib/examples/zpipe.c inf() function for explanation. */
     418             :                 /* This works as long as this function is not used for streaming. Required to catch very short invalid data. */
     419          22 :                 status = (status == Z_OK) ? Z_DATA_ERROR : status;
     420             :         }
     421         130 :         return status;
     422             : }
     423             : /* }}} */
     424             : 
     425             : /* {{{ php_zlib_decode() */
     426         122 : static int php_zlib_decode(const char *in_buf, size_t in_len, char **out_buf, size_t *out_len, int encoding, size_t max_len)
     427             : {
     428         122 :         int status = Z_DATA_ERROR;
     429             :         z_stream Z;
     430             : 
     431         122 :         memset(&Z, 0, sizeof(z_stream));
     432         122 :         Z.zalloc = php_zlib_alloc;
     433         122 :         Z.zfree = php_zlib_free;
     434             : 
     435         122 :         if (in_len) {
     436             : retry_raw_inflate:
     437         130 :                 status = inflateInit2(&Z, encoding);
     438         130 :                 if (Z_OK == status) {
     439         130 :                         Z.next_in = (Bytef *) in_buf;
     440         130 :                         Z.avail_in = in_len + 1; /* NOTE: data must be zero terminated */
     441             : 
     442         130 :                         switch (status = php_zlib_inflate_rounds(&Z, max_len, out_buf, out_len)) {
     443             :                                 case Z_STREAM_END:
     444         108 :                                         inflateEnd(&Z);
     445         108 :                                         return SUCCESS;
     446             : 
     447             :                                 case Z_DATA_ERROR:
     448             :                                         /* raw deflated data? */
     449          20 :                                         if (PHP_ZLIB_ENCODING_ANY == encoding) {
     450          12 :                                                 inflateEnd(&Z);
     451          12 :                                                 encoding = PHP_ZLIB_ENCODING_RAW;
     452          12 :                                                 goto retry_raw_inflate;
     453             :                                         }
     454             :                         }
     455          10 :                         inflateEnd(&Z);
     456             :                 }
     457             :         }
     458             : 
     459          14 :         *out_buf = NULL;
     460          14 :         *out_len = 0;
     461             : 
     462          14 :         php_error_docref(NULL, E_WARNING, "%s", zError(status));
     463          14 :         return FAILURE;
     464             : }
     465             : /* }}} */
     466             : 
     467             : /* {{{ php_zlib_cleanup_ob_gzhandler_mess() */
     468       20911 : static void php_zlib_cleanup_ob_gzhandler_mess(void)
     469             : {
     470       20911 :         if (ZLIBG(ob_gzhandler)) {
     471           0 :                 deflateEnd(&(ZLIBG(ob_gzhandler)->Z));
     472           0 :                 php_zlib_output_handler_context_dtor(ZLIBG(ob_gzhandler));
     473           0 :                 ZLIBG(ob_gzhandler) = NULL;
     474             :         }
     475       20911 : }
     476             : /* }}} */
     477             : 
     478             : /* {{{ proto string ob_gzhandler(string data, int flags)
     479             :    Legacy hack */
     480           1 : static PHP_FUNCTION(ob_gzhandler)
     481             : {
     482             :         char *in_str;
     483             :         size_t in_len;
     484           1 :         zend_long flags = 0;
     485           1 :         php_output_context ctx = {0};
     486             :         int encoding, rv;
     487             : 
     488             :         /*
     489             :          * NOTE that the real ob_gzhandler is an alias to "zlib output compression".
     490             :          * This is a really bad hack, because
     491             :          * - we have to initialize a php_zlib_context on demand
     492             :          * - we have to clean it up in RSHUTDOWN
     493             :          * - OG(running) is not set or set to any other output handler
     494             :          * - we have to mess around with php_output_context */
     495             : 
     496           1 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "sl", &in_str, &in_len, &flags)) {
     497           0 :                 RETURN_FALSE;
     498             :         }
     499             : 
     500           1 :         if (!(encoding = php_zlib_output_encoding())) {
     501           1 :                 RETURN_FALSE;
     502             :         }
     503             : 
     504           0 :         if (flags & PHP_OUTPUT_HANDLER_START) {
     505           0 :                 switch (encoding) {
     506             :                         case PHP_ZLIB_ENCODING_GZIP:
     507           0 :                                 sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1);
     508           0 :                                 break;
     509             :                         case PHP_ZLIB_ENCODING_DEFLATE:
     510           0 :                                 sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1);
     511             :                                 break;
     512             :                 }
     513           0 :                 sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 0);
     514             :         }
     515             : 
     516           0 :         if (!ZLIBG(ob_gzhandler)) {
     517           0 :                 ZLIBG(ob_gzhandler) = php_zlib_output_handler_context_init();
     518             :         }
     519             : 
     520           0 :         ctx.op = flags;
     521           0 :         ctx.in.data = in_str;
     522           0 :         ctx.in.used = in_len;
     523             : 
     524           0 :         rv = php_zlib_output_handler_ex(ZLIBG(ob_gzhandler), &ctx);
     525             : 
     526           0 :         if (SUCCESS != rv) {
     527           0 :                 if (ctx.out.data && ctx.out.free) {
     528           0 :                         efree(ctx.out.data);
     529             :                 }
     530           0 :                 php_zlib_cleanup_ob_gzhandler_mess();
     531           0 :                 RETURN_FALSE;
     532             :         }
     533             : 
     534           0 :         if (ctx.out.data) {
     535           0 :                 RETVAL_STRINGL(ctx.out.data, ctx.out.used);
     536           0 :                 if (ctx.out.free) {
     537           0 :                         efree(ctx.out.data);
     538             :                 }
     539             :         } else {
     540           0 :                 RETVAL_EMPTY_STRING();
     541             :         }
     542             : }
     543             : /* }}} */
     544             : 
     545             : /* {{{ proto string zlib_get_coding_type(void)
     546             :    Returns the coding type used for output compression */
     547           0 : static PHP_FUNCTION(zlib_get_coding_type)
     548             : {
     549           0 :         if (zend_parse_parameters_none() == FAILURE) {
     550           0 :                 return;
     551             :         }
     552           0 :         switch (ZLIBG(compression_coding)) {
     553             :                 case PHP_ZLIB_ENCODING_GZIP:
     554           0 :                         RETURN_STRINGL("gzip", sizeof("gzip") - 1);
     555             :                 case PHP_ZLIB_ENCODING_DEFLATE:
     556           0 :                         RETURN_STRINGL("deflate", sizeof("deflate") - 1);
     557             :                 default:
     558           0 :                         RETURN_FALSE;
     559             :         }
     560             : }
     561             : /* }}} */
     562             : 
     563             : /* {{{ proto array gzfile(string filename [, int use_include_path])
     564             :    Read and uncompress entire .gz-file into an array */
     565          73 : static PHP_FUNCTION(gzfile)
     566             : {
     567             :         char *filename;
     568             :         size_t filename_len;
     569          73 :         int flags = REPORT_ERRORS;
     570          73 :         char buf[8192] = {0};
     571          73 :         register int i = 0;
     572          73 :         zend_long use_include_path = 0;
     573             :         php_stream *stream;
     574             : 
     575          73 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &filename, &filename_len, &use_include_path)) {
     576          25 :                 return;
     577             :         }
     578             : 
     579          48 :         if (use_include_path) {
     580          16 :                 flags |= USE_PATH;
     581             :         }
     582             : 
     583             :         /* using a stream here is a bit more efficient (resource wise) than php_gzopen_wrapper */
     584          48 :         stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC);
     585             : 
     586          48 :         if (!stream) {
     587             :                 /* Error reporting is already done by stream code */
     588          21 :                 RETURN_FALSE;
     589             :         }
     590             : 
     591             :         /* Initialize return array */
     592          27 :         array_init(return_value);
     593             : 
     594             :         /* Now loop through the file and do the magic quotes thing if needed */
     595          27 :         memset(buf, 0, sizeof(buf));
     596             : 
     597         195 :         while (php_stream_gets(stream, buf, sizeof(buf) - 1) != NULL) {
     598         141 :                 add_index_string(return_value, i++, buf);
     599             :         }
     600          27 :         php_stream_close(stream);
     601             : }
     602             : /* }}} */
     603             : 
     604             : /* {{{ proto resource gzopen(string filename, string mode [, int use_include_path])
     605             :    Open a .gz-file and return a .gz-file pointer */
     606         208 : static PHP_FUNCTION(gzopen)
     607             : {
     608             :         char *filename;
     609             :         char *mode;
     610             :         size_t filename_len, mode_len;
     611         208 :         int flags = REPORT_ERRORS;
     612             :         php_stream *stream;
     613         208 :         zend_long use_include_path = 0;
     614             : 
     615         208 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ps|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) {
     616          27 :                 return;
     617             :         }
     618             : 
     619         181 :         if (use_include_path) {
     620          23 :                 flags |= USE_PATH;
     621             :         }
     622             : 
     623         181 :         stream = php_stream_gzopen(NULL, filename, mode, flags, NULL, NULL STREAMS_CC);
     624             : 
     625         181 :         if (!stream) {
     626          52 :                 RETURN_FALSE;
     627             :         }
     628         129 :         php_stream_to_zval(stream, return_value);
     629             : }
     630             : /* }}} */
     631             : 
     632             : /* {{{ proto int readgzfile(string filename [, int use_include_path])
     633             :    Output a .gz-file */
     634          68 : static PHP_FUNCTION(readgzfile)
     635             : {
     636             :         char *filename;
     637             :         size_t filename_len;
     638          68 :         int flags = REPORT_ERRORS;
     639             :         php_stream *stream;
     640             :         size_t size;
     641          68 :         zend_long use_include_path = 0;
     642             : 
     643          68 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &filename, &filename_len, &use_include_path) == FAILURE) {
     644          23 :                 return;
     645             :         }
     646             : 
     647          45 :         if (use_include_path) {
     648          14 :                 flags |= USE_PATH;
     649             :         }
     650             : 
     651          45 :         stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC);
     652             : 
     653          45 :         if (!stream) {
     654          20 :                 RETURN_FALSE;
     655             :         }
     656          25 :         size = php_stream_passthru(stream);
     657          25 :         php_stream_close(stream);
     658          25 :         RETURN_LONG(size);
     659             : }
     660             : /* }}} */
     661             : 
     662             : #define PHP_ZLIB_ENCODE_FUNC(name, default_encoding) \
     663             : static PHP_FUNCTION(name) \
     664             : { \
     665             :         zend_string *in, *out; \
     666             :         zend_long level = -1; \
     667             :         zend_long encoding = default_encoding; \
     668             :         if (default_encoding) { \
     669             :                 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "S|ll", &in, &level, &encoding)) { \
     670             :                         return; \
     671             :                 } \
     672             :         } else { \
     673             :                 if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "Sl|l", &in, &encoding, &level)) { \
     674             :                         return; \
     675             :                 } \
     676             :         } \
     677             :         if (level < -1 || level > 9) { \
     678             :                 php_error_docref(NULL, E_WARNING, "compression level (%pd) must be within -1..9", level); \
     679             :                 RETURN_FALSE; \
     680             :         } \
     681             :         switch (encoding) { \
     682             :                 case PHP_ZLIB_ENCODING_RAW: \
     683             :                 case PHP_ZLIB_ENCODING_GZIP: \
     684             :                 case PHP_ZLIB_ENCODING_DEFLATE: \
     685             :                         break; \
     686             :                 default: \
     687             :                         php_error_docref(NULL, E_WARNING, "encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE"); \
     688             :                         RETURN_FALSE; \
     689             :         } \
     690             :         if ((out = php_zlib_encode(in->val, in->len, encoding, level)) == NULL) { \
     691             :                 RETURN_FALSE; \
     692             :         } \
     693             :         RETURN_STR(out); \
     694             : }
     695             : 
     696             : #define PHP_ZLIB_DECODE_FUNC(name, encoding) \
     697             : static PHP_FUNCTION(name) \
     698             : { \
     699             :         char *in_buf, *out_buf; \
     700             :         size_t in_len; \
     701             :         size_t out_len; \
     702             :         zend_long max_len = 0; \
     703             :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &in_buf, &in_len, &max_len)) { \
     704             :                 return; \
     705             :         } \
     706             :         if (max_len < 0) { \
     707             :                 php_error_docref(NULL, E_WARNING, "length (%pd) must be greater or equal zero", max_len); \
     708             :                 RETURN_FALSE; \
     709             :         } \
     710             :         if (SUCCESS != php_zlib_decode(in_buf, in_len, &out_buf, &out_len, encoding, max_len)) { \
     711             :                 RETURN_FALSE; \
     712             :         } \
     713             :         RETVAL_STRINGL(out_buf, out_len); \
     714             :         efree(out_buf); \
     715             : }
     716             : 
     717             : /* {{{ proto binary zlib_encode(binary data, int encoding[, int level = -1])
     718             :    Compress data with the specified encoding */
     719           3 : PHP_ZLIB_ENCODE_FUNC(zlib_encode, 0);
     720             : /* }}} */
     721             : 
     722             : /* {{{ proto binary zlib_decode(binary data[, int max_decoded_len])
     723             :    Uncompress any raw/gzip/zlib encoded data */
     724          74 : PHP_ZLIB_DECODE_FUNC(zlib_decode, PHP_ZLIB_ENCODING_ANY);
     725             : /* }}} */
     726             : 
     727             : /* NOTE: The naming of these userland functions was quite unlucky */
     728             : /* {{{ proto binary gzdeflate(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_RAW])
     729             :    Encode data with the raw deflate encoding */
     730          48 : PHP_ZLIB_ENCODE_FUNC(gzdeflate, PHP_ZLIB_ENCODING_RAW);
     731             : /* }}} */
     732             : 
     733             : /* {{{ proto binary gzencode(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_GZIP])
     734             :    Encode data with the gzip encoding */
     735          56 : PHP_ZLIB_ENCODE_FUNC(gzencode, PHP_ZLIB_ENCODING_GZIP);
     736             : /* }}} */
     737             : 
     738             : /* {{{ proto binary gzcompress(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_DEFLATE])
     739             :    Encode data with the zlib encoding */
     740          47 : PHP_ZLIB_ENCODE_FUNC(gzcompress, PHP_ZLIB_ENCODING_DEFLATE);
     741             : /* }}} */
     742             : 
     743             : /* {{{ proto binary gzinflate(binary data[, int max_decoded_len])
     744             :    Decode raw deflate encoded data */
     745          90 : PHP_ZLIB_DECODE_FUNC(gzinflate, PHP_ZLIB_ENCODING_RAW);
     746             : /* }}} */
     747             : 
     748             : /* {{{ proto binary gzdecode(binary data[, int max_decoded_len])
     749             :    Decode gzip encoded data */
     750           2 : PHP_ZLIB_DECODE_FUNC(gzdecode, PHP_ZLIB_ENCODING_GZIP);
     751             : /* }}} */
     752             : 
     753             : /* {{{ proto binary gzuncompress(binary data[, int max_decoded_len])
     754             :    Decode zlib encoded data */
     755          76 : PHP_ZLIB_DECODE_FUNC(gzuncompress, PHP_ZLIB_ENCODING_DEFLATE);
     756             : /* }}} */
     757             : 
     758          91 : static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, size_t *dictlen) {
     759             :         zval *option_buffer;
     760             : 
     761          91 :         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("dictionary"))) != NULL) {
     762             :                 HashTable *dictionary;
     763             : 
     764           3 :                 ZVAL_DEREF(option_buffer);
     765           3 :                 if (Z_TYPE_P(option_buffer) != IS_ARRAY) {
     766           0 :                         php_error_docref(NULL, E_WARNING, "dictionary must be of type array, got %s", zend_get_type_by_const(Z_TYPE_P(option_buffer)));
     767           0 :                         return 0;
     768             :                 }
     769           3 :                 dictionary = Z_ARR_P(option_buffer);
     770             : 
     771           3 :                 if (zend_hash_num_elements(dictionary) > 0) {
     772             :                         char *dictptr;
     773             :                         zval *cur;
     774           3 :                         zend_string **strings = emalloc(sizeof(zend_string *) * zend_hash_num_elements(dictionary));
     775           3 :                         zend_string **end, **ptr = strings - 1;
     776             : 
     777         159 :                         ZEND_HASH_FOREACH_VAL(dictionary, cur) {
     778             :                                 int i;
     779             : 
     780         156 :                                 *++ptr = zval_get_string(cur);
     781          78 :                                 if (!*ptr || (*ptr)->len == 0) {
     782           0 :                                         if (*ptr) {
     783           0 :                                                 efree(*ptr);
     784             :                                         }
     785           0 :                                         while (--ptr >= strings) {
     786           0 :                                                 efree(ptr);
     787             :                                         }
     788           0 :                                         efree(strings);
     789           0 :                                         php_error_docref(NULL, E_WARNING, "dictionary entries must be non-empty strings");
     790           0 :                                         return 0;
     791             :                                 }
     792         156 :                                 for (i = 0; i < (*ptr)->len; i++) {
     793          78 :                                         if ((*ptr)->val[i] == 0) {
     794             :                                                 do {
     795           0 :                                                         efree(ptr);
     796           0 :                                                 } while (--ptr >= strings);
     797           0 :                                                 efree(strings);
     798           0 :                                                 php_error_docref(NULL, E_WARNING, "dictionary entries must not contain a NULL-byte");
     799           0 :                                                 return 0;
     800             :                                         }
     801             :                                 }
     802             : 
     803          78 :                                 *dictlen += (*ptr)->len + 1;
     804             :                         } ZEND_HASH_FOREACH_END();
     805             : 
     806           3 :                         dictptr = *dict = emalloc(*dictlen);
     807           3 :                         ptr = strings;
     808           3 :                         end = strings + zend_hash_num_elements(dictionary);
     809             :                         do {
     810          78 :                                 memcpy(dictptr, *ptr, (*ptr)->len);
     811          78 :                                 dictptr += (*ptr)->len;
     812          78 :                                 *dictptr++ = 0;
     813          78 :                                 zend_string_release(*ptr);
     814          78 :                         } while (++ptr != end);
     815           3 :                         efree(strings);
     816             :                 }
     817             :         }
     818             : 
     819          91 :         return 1;
     820             : }
     821             : 
     822             : /* {{{ proto resource inflate_init(int encoding)
     823             :    Initialize an incremental inflate context with the specified encoding */
     824          51 : PHP_FUNCTION(inflate_init)
     825             : {
     826             :         z_stream *ctx;
     827          51 :         zend_long encoding, window = 15;
     828          51 :         char *dict = NULL;
     829          51 :         size_t dictlen = 0;
     830          51 :         HashTable *options = NULL;
     831             :         zval *option_buffer;
     832             : 
     833          51 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) {
     834           1 :                 return;
     835             :         }
     836             : 
     837          50 :         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) {
     838           0 :                 window = zval_get_long(option_buffer);
     839             :         }
     840          50 :         if (window < 8 || window > 15) {
     841           0 :                 php_error_docref(NULL, E_WARNING, "zlib window size (lograithm) (%pd) must be within 8..15", window);
     842           0 :                 RETURN_FALSE;
     843             :         }
     844             : 
     845          50 :         if (!zlib_create_dictionary_string(options, &dict, &dictlen)) {
     846           0 :                 RETURN_FALSE;
     847             :         }
     848             : 
     849          50 :         switch (encoding) {
     850             :                 case PHP_ZLIB_ENCODING_RAW:
     851             :                 case PHP_ZLIB_ENCODING_GZIP:
     852             :                 case PHP_ZLIB_ENCODING_DEFLATE:
     853          49 :                         break;
     854             :                 default:
     855           1 :                         php_error_docref(NULL, E_WARNING, "encoding mode must be ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE");
     856           1 :                         RETURN_FALSE;
     857             :         }
     858             : 
     859          49 :         ctx = ecalloc(1, sizeof(php_zlib_context));
     860          49 :         ctx->zalloc = php_zlib_alloc;
     861          49 :         ctx->zfree = php_zlib_free;
     862          49 :         ((php_zlib_context *) ctx)->inflateDict = dict;
     863          49 :         ((php_zlib_context *) ctx)->inflateDictlen = dictlen;
     864             : 
     865          49 :         if (encoding < 0) {
     866          15 :                 encoding += 15 - window;
     867             :         } else {
     868          34 :                 encoding -= 15 - window;
     869             :         }
     870             : 
     871          49 :         if (Z_OK == inflateInit2(ctx, encoding)) {
     872          49 :                 RETURN_RES(zend_register_resource(ctx, le_inflate));
     873             :         } else {
     874           0 :                 efree(ctx);
     875           0 :                 php_error_docref(NULL, E_WARNING, "failed allocating zlib.inflate context");
     876           0 :                 RETURN_FALSE;
     877             :         }
     878             : }
     879             : /* }}} */
     880             : 
     881             : /* {{{ proto string inflate_add(resource context, string encoded_data[, int flush_mode = ZLIB_SYNC_FLUSH])
     882             :    Incrementally inflate encoded data in the specified context */
     883      979183 : PHP_FUNCTION(inflate_add)
     884             : {
     885             :         zend_string *out;
     886             :         char *in_buf;
     887      979183 :         size_t in_len, buffer_used = 0, CHUNK_SIZE = 8192;
     888             :         zval *res;
     889             :         z_stream *ctx;
     890      979183 :         zend_long flush_type = Z_SYNC_FLUSH;
     891             :         int status;
     892             : 
     893      979183 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &res, &in_buf, &in_len, &flush_type)) {
     894           0 :                 return;
     895             :         }
     896             : 
     897      979183 :         if (!(ctx = zend_fetch_resource_ex(res, NULL, le_inflate))) {
     898           1 :                 php_error_docref(NULL, E_WARNING, "Invalid zlib.inflate resource");
     899           1 :                 RETURN_FALSE;
     900             :         }
     901             : 
     902      979182 :         switch (flush_type) {
     903             :                 case Z_NO_FLUSH:
     904             :                 case Z_PARTIAL_FLUSH:
     905             :                 case Z_SYNC_FLUSH:
     906             :                 case Z_FULL_FLUSH:
     907             :                 case Z_BLOCK:
     908             :                 case Z_FINISH:
     909      979181 :                         break;
     910             : 
     911             :                 default:
     912           1 :                         php_error_docref(NULL, E_WARNING,
     913             :                                 "flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH");
     914           1 :                         RETURN_FALSE;
     915             :         }
     916             : 
     917      979181 :         if (in_len <= 0 && flush_type != Z_FINISH) {
     918           0 :                 RETURN_EMPTY_STRING();
     919             :         }
     920             : 
     921     1958362 :         out = zend_string_alloc((in_len > CHUNK_SIZE) ? in_len : CHUNK_SIZE, 0);
     922      979181 :         ctx->next_in = (Bytef *) in_buf;
     923      979181 :         ctx->next_out = (Bytef *) out->val;
     924      979181 :         ctx->avail_in = in_len;
     925      979181 :         ctx->avail_out = out->len;
     926             : 
     927             :         do {
     928      979227 :                 status = inflate(ctx, flush_type);
     929      979227 :                 buffer_used = out->len - ctx->avail_out;
     930             : 
     931      979227 :                 switch (status) {
     932             :                         case Z_OK:
     933      979145 :                                 if (ctx->avail_out == 0) {
     934             :                                         /* more output buffer space needed; realloc and try again */
     935          60 :                                         out = zend_string_realloc(out, out->len + CHUNK_SIZE, 0);
     936          30 :                                         ctx->avail_out = CHUNK_SIZE;
     937          30 :                                         ctx->next_out = (Bytef *) out->val + buffer_used;
     938          30 :                                         break;
     939             :                                 } else {
     940      979115 :                                         goto complete;
     941             :                                 }
     942             :                         case Z_STREAM_END:
     943          48 :                                 inflateReset(ctx);
     944          48 :                                 goto complete;
     945             :                         case Z_BUF_ERROR:
     946          32 :                                 if (flush_type == Z_FINISH && ctx->avail_out == 0) {
     947             :                                         /* more output buffer space needed; realloc and try again */
     948          30 :                                         out = zend_string_realloc(out, out->len + CHUNK_SIZE, 0);
     949          15 :                                         ctx->avail_out = CHUNK_SIZE;
     950          15 :                                         ctx->next_out = (Bytef *) out->val + buffer_used;
     951          15 :                                         break;
     952             :                                 } else {
     953             :                                         /* No more input data; we're finished */
     954             :                                         goto complete;
     955             :                                 }
     956             :                         case Z_NEED_DICT:
     957           2 :                                 if (((php_zlib_context *) ctx)->inflateDict) {
     958           2 :                                         php_zlib_context *php_ctx = (php_zlib_context *) ctx;
     959           2 :                                         switch (inflateSetDictionary(ctx, (Bytef *) php_ctx->inflateDict, php_ctx->inflateDictlen)) {
     960             :                                                 case Z_OK:
     961           1 :                                                         efree(php_ctx->inflateDict);
     962           1 :                                                         php_ctx->inflateDict = NULL;
     963           1 :                                                         break;
     964             :                                                 case Z_DATA_ERROR:
     965           1 :                                                         php_error_docref(NULL, E_WARNING, "dictionary does not match expected dictionary (incorrect adler32 hash)");
     966           1 :                                                         efree(php_ctx->inflateDict);
     967             :                                                         zend_string_release(out);
     968           1 :                                                         php_ctx->inflateDict = NULL;
     969           1 :                                                         RETURN_FALSE;
     970             :                                                 EMPTY_SWITCH_DEFAULT_CASE()
     971             :                                         }
     972           1 :                                         break;
     973             :                                 } else {
     974           0 :                                         php_error_docref(NULL, E_WARNING, "inflating this data requires a preset dictionary, please specify it in the options array of inflate_init()");
     975           0 :                                         RETURN_FALSE;
     976             :                                 }
     977             :                         default:
     978             :                                 zend_string_release(out);
     979           0 :                                 php_error_docref(NULL, E_WARNING, "%s", zError(status));
     980           0 :                                 RETURN_FALSE;
     981             :                 }
     982          46 :         } while (1);
     983             : 
     984             :         complete: {
     985      979180 :                 out = zend_string_realloc(out, buffer_used, 0);
     986      979180 :                 out->val[buffer_used] = 0;
     987      979180 :                 RETURN_STR(out);
     988             :         }
     989             : }
     990             : /* }}} */
     991             : 
     992             : /* {{{ proto resource deflate_init(int encoding[, array options])
     993             :    Initialize an incremental deflate context using the specified encoding */
     994          45 : PHP_FUNCTION(deflate_init)
     995             : {
     996             :         z_stream *ctx;
     997          45 :         zend_long encoding, level = -1, memory = 8, window = 15, strategy = Z_DEFAULT_STRATEGY;
     998          45 :         char *dict = NULL;
     999          45 :         size_t dictlen = 0;
    1000          45 :         HashTable *options = NULL;
    1001             :         zval *option_buffer;
    1002             : 
    1003          45 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) {
    1004           0 :                 return;
    1005             :         }
    1006             : 
    1007          45 :         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("level"))) != NULL) {
    1008           2 :                 level = zval_get_long(option_buffer);
    1009             :         }
    1010          45 :         if (level < -1 || level > 9) {
    1011           2 :                 php_error_docref(NULL, E_WARNING, "compression level (%pd) must be within -1..9", level);
    1012           2 :                 RETURN_FALSE;
    1013             :         }
    1014             : 
    1015          43 :         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("memory"))) != NULL) {
    1016           2 :                 memory = zval_get_long(option_buffer);
    1017             :         }
    1018          43 :         if (memory < 1 || memory > 9) {
    1019           2 :                 php_error_docref(NULL, E_WARNING, "compression memory level (%pd) must be within 1..9", memory);
    1020           2 :                 RETURN_FALSE;
    1021             :         }
    1022             : 
    1023          41 :         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) {
    1024           0 :                 window = zval_get_long(option_buffer);
    1025             :         }
    1026          41 :         if (window < 8 || window > 15) {
    1027           0 :                 php_error_docref(NULL, E_WARNING, "zlib window size (logarithm) (%pd) must be within 8..15", window);
    1028           0 :                 RETURN_FALSE;
    1029             :         }
    1030             : 
    1031          41 :         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("strategy"))) != NULL) {
    1032           0 :                 strategy = zval_get_long(option_buffer);
    1033             :         }
    1034          41 :         switch (strategy) {
    1035             :                 case Z_FILTERED:
    1036             :                 case Z_HUFFMAN_ONLY:
    1037             :                 case Z_RLE:
    1038             :                 case Z_FIXED:
    1039             :                 case Z_DEFAULT_STRATEGY:
    1040          41 :                         break;
    1041             :                 default:
    1042           0 :                         php_error_docref(NULL, E_WARNING, "strategy must be one of ZLIB_FILTERED, ZLIB_HUFFMAN_ONLY, ZLIB_RLE, ZLIB_FIXED or ZLIB_DEFAULT_STRATEGY", strategy);
    1043           0 :                         RETURN_FALSE;
    1044             :         }
    1045             : 
    1046          41 :         if (!zlib_create_dictionary_string(options, &dict, &dictlen)) {
    1047           0 :                 RETURN_FALSE;
    1048             :         }
    1049             : 
    1050          41 :         switch (encoding) {
    1051             :                 case PHP_ZLIB_ENCODING_RAW:
    1052             :                 case PHP_ZLIB_ENCODING_GZIP:
    1053             :                 case PHP_ZLIB_ENCODING_DEFLATE:
    1054          40 :                         break;
    1055             :                 default:
    1056           1 :                         php_error_docref(NULL, E_WARNING,
    1057             :                                 "encoding mode must be ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE");
    1058           1 :                         RETURN_FALSE;
    1059             :         }
    1060             : 
    1061          40 :         ctx = ecalloc(1, sizeof(php_zlib_context));
    1062          40 :         ctx->zalloc = php_zlib_alloc;
    1063          40 :         ctx->zfree = php_zlib_free;
    1064             : 
    1065          40 :         if (encoding < 0) {
    1066          12 :                 encoding += 15 - window;
    1067             :         } else {
    1068          28 :                 encoding -= 15 - window;
    1069             :         }
    1070             : 
    1071          40 :         if (Z_OK == deflateInit2(ctx, level, Z_DEFLATED, encoding, memory, strategy)) {
    1072          40 :                 if (dict) {
    1073           1 :                         int success = deflateSetDictionary(ctx, (Bytef *) dict, dictlen);
    1074             :                         ZEND_ASSERT(success == Z_OK);
    1075           1 :                         efree(dict);
    1076             :                 }
    1077             : 
    1078          40 :                 RETURN_RES(zend_register_resource(ctx, le_deflate));
    1079             :         } else {
    1080           0 :                 efree(ctx);
    1081           0 :                 php_error_docref(NULL, E_WARNING, "failed allocating zlib.deflate context");
    1082           0 :                 RETURN_FALSE;
    1083             :         }
    1084             : }
    1085             : /* }}} */
    1086             : 
    1087             : /* {{{ proto string deflate_add(resource context, string data[, int flush_mode = ZLIB_SYNC_FLUSH])
    1088             :    Incrementally deflate data in the specified context */
    1089         478 : PHP_FUNCTION(deflate_add)
    1090             : {
    1091             :         zend_string *out;
    1092             :         char *in_buf;
    1093             :         size_t in_len, out_size;
    1094             :         zval *res;
    1095             :         z_stream *ctx;
    1096         478 :         zend_long flush_type = Z_SYNC_FLUSH;
    1097             :         int status;
    1098             : 
    1099         478 :         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &res, &in_buf, &in_len, &flush_type)) {
    1100           0 :                 return;
    1101             :         }
    1102             : 
    1103         478 :         if (!(ctx = zend_fetch_resource_ex(res, NULL, le_deflate))) {
    1104           1 :                 php_error_docref(NULL, E_WARNING, "Invalid deflate resource");
    1105           1 :                 RETURN_FALSE;
    1106             :         }
    1107             : 
    1108         477 :         switch (flush_type) {
    1109             :                 case Z_BLOCK:
    1110             : #if ZLIB_VERNUM < 0x1240L
    1111           1 :                         php_error_docref(NULL, E_WARNING,
    1112             :                                 "zlib >= 1.2.4 required for BLOCK deflate; current version: %s", ZLIB_VERSION);
    1113           1 :                         RETURN_FALSE;
    1114             : #endif
    1115             :                 case Z_NO_FLUSH:
    1116             :                 case Z_PARTIAL_FLUSH:
    1117             :                 case Z_SYNC_FLUSH:
    1118             :                 case Z_FULL_FLUSH:
    1119             :                 case Z_FINISH:
    1120         475 :                         break;
    1121             : 
    1122             :                 default:
    1123           1 :                         php_error_docref(NULL, E_WARNING,
    1124             :                                 "flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH");
    1125           1 :                         RETURN_FALSE;
    1126             :         }
    1127             : 
    1128         475 :         if (in_len <= 0 && flush_type != Z_FINISH) {
    1129           0 :                 RETURN_EMPTY_STRING();
    1130             :         }
    1131             : 
    1132         475 :         out_size = PHP_ZLIB_BUFFER_SIZE_GUESS(ctx->total_in + in_len);
    1133         475 :         out_size = (ctx->total_out >= out_size) ? 16 : (out_size - ctx->total_out);
    1134         475 :         out_size = (out_size < 16) ? 16 : out_size;
    1135         475 :         out = zend_string_alloc(out_size, 0);
    1136             : 
    1137         475 :         ctx->next_in = (Bytef *) in_buf;
    1138         475 :         ctx->next_out = (Bytef *) out->val;
    1139         475 :         ctx->avail_in = in_len;
    1140         475 :         ctx->avail_out = out->len;
    1141             : 
    1142         475 :         status = deflate(ctx, flush_type);
    1143         475 :         switch (status) {
    1144             :                 case Z_OK:
    1145         436 :                         out->len = (char *) ctx->next_out - out->val;
    1146         436 :                         out->val[out->len] = 0;
    1147         436 :                         RETURN_STR(out);
    1148             :                         break;
    1149             :                 case Z_STREAM_END:
    1150          39 :                         out->len = (char *) ctx->next_out - out->val;
    1151          39 :                         out->val[out->len] = 0;
    1152          39 :                         deflateReset(ctx);
    1153          39 :                         RETURN_STR(out);
    1154             :                         break;
    1155             :                 default:
    1156             :                         zend_string_release(out);
    1157           0 :                         php_error_docref(NULL, E_WARNING, "zlib error (%s)", zError(status));
    1158           0 :                         RETURN_FALSE;
    1159             :         }
    1160             : }
    1161             : /* }}} */
    1162             : 
    1163             : #ifdef COMPILE_DL_ZLIB
    1164             : #ifdef ZTS
    1165             : ZEND_TSRMLS_CACHE_DEFINE();
    1166             : #endif
    1167             : ZEND_GET_MODULE(php_zlib)
    1168             : #endif
    1169             : 
    1170             : /* {{{ arginfo */
    1171             : ZEND_BEGIN_ARG_INFO_EX(arginfo_ob_gzhandler, 0, 0, 2)
    1172             :         ZEND_ARG_INFO(0, data)
    1173             :         ZEND_ARG_INFO(0, flags)
    1174             : ZEND_END_ARG_INFO()
    1175             : 
    1176             : ZEND_BEGIN_ARG_INFO(arginfo_zlib_get_coding_type, 0)
    1177             : ZEND_END_ARG_INFO()
    1178             : 
    1179             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzfile, 0, 0, 1)
    1180             :         ZEND_ARG_INFO(0, filename)
    1181             :         ZEND_ARG_INFO(0, use_include_path)
    1182             : ZEND_END_ARG_INFO()
    1183             : 
    1184             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzopen, 0, 0, 2)
    1185             :         ZEND_ARG_INFO(0, filename)
    1186             :         ZEND_ARG_INFO(0, mode)
    1187             :         ZEND_ARG_INFO(0, use_include_path)
    1188             : ZEND_END_ARG_INFO()
    1189             : 
    1190             : ZEND_BEGIN_ARG_INFO_EX(arginfo_readgzfile, 0, 0, 1)
    1191             :         ZEND_ARG_INFO(0, filename)
    1192             :         ZEND_ARG_INFO(0, use_include_path)
    1193             : ZEND_END_ARG_INFO()
    1194             : 
    1195             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zlib_encode, 0, 0, 2)
    1196             :         ZEND_ARG_INFO(0, data)
    1197             :         ZEND_ARG_INFO(0, encoding)
    1198             :         ZEND_ARG_INFO(0, level)
    1199             : ZEND_END_ARG_INFO()
    1200             : 
    1201             : ZEND_BEGIN_ARG_INFO_EX(arginfo_zlib_decode, 0, 0, 1)
    1202             :         ZEND_ARG_INFO(0, data)
    1203             :         ZEND_ARG_INFO(0, max_decoded_len)
    1204             : ZEND_END_ARG_INFO()
    1205             : 
    1206             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzdeflate, 0, 0, 1)
    1207             :         ZEND_ARG_INFO(0, data)
    1208             :         ZEND_ARG_INFO(0, level)
    1209             :         ZEND_ARG_INFO(0, encoding)
    1210             : ZEND_END_ARG_INFO()
    1211             : 
    1212             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzencode, 0, 0, 1)
    1213             :         ZEND_ARG_INFO(0, data)
    1214             :         ZEND_ARG_INFO(0, level)
    1215             :         ZEND_ARG_INFO(0, encoding)
    1216             : ZEND_END_ARG_INFO()
    1217             : 
    1218             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzcompress, 0, 0, 1)
    1219             :         ZEND_ARG_INFO(0, data)
    1220             :         ZEND_ARG_INFO(0, level)
    1221             :         ZEND_ARG_INFO(0, encoding)
    1222             : ZEND_END_ARG_INFO()
    1223             : 
    1224             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzinflate, 0, 0, 1)
    1225             :         ZEND_ARG_INFO(0, data)
    1226             :         ZEND_ARG_INFO(0, max_decoded_len)
    1227             : ZEND_END_ARG_INFO()
    1228             : 
    1229             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzdecode, 0, 0, 1)
    1230             :         ZEND_ARG_INFO(0, data)
    1231             :         ZEND_ARG_INFO(0, max_decoded_len)
    1232             : ZEND_END_ARG_INFO()
    1233             : 
    1234             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzuncompress, 0, 0, 1)
    1235             :         ZEND_ARG_INFO(0, data)
    1236             :         ZEND_ARG_INFO(0, max_decoded_len)
    1237             : ZEND_END_ARG_INFO()
    1238             : 
    1239             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzputs, 0, 0, 2)
    1240             :         ZEND_ARG_INFO(0, fp)
    1241             :         ZEND_ARG_INFO(0, str)
    1242             :         ZEND_ARG_INFO(0, length)
    1243             : ZEND_END_ARG_INFO()
    1244             : 
    1245             : ZEND_BEGIN_ARG_INFO(arginfo_gzpassthru, 0)
    1246             :         ZEND_ARG_INFO(0, fp)
    1247             : ZEND_END_ARG_INFO()
    1248             : 
    1249             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzseek, 0, 0, 2)
    1250             :         ZEND_ARG_INFO(0, fp)
    1251             :         ZEND_ARG_INFO(0, offset)
    1252             :         ZEND_ARG_INFO(0, whence)
    1253             : ZEND_END_ARG_INFO()
    1254             : 
    1255             : ZEND_BEGIN_ARG_INFO(arginfo_gzread, 0)
    1256             :         ZEND_ARG_INFO(0, fp)
    1257             :         ZEND_ARG_INFO(0, length)
    1258             : ZEND_END_ARG_INFO()
    1259             : 
    1260             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzgetss, 0, 0, 1)
    1261             :         ZEND_ARG_INFO(0, fp)
    1262             :         ZEND_ARG_INFO(0, length)
    1263             :         ZEND_ARG_INFO(0, allowable_tags)
    1264             : ZEND_END_ARG_INFO()
    1265             : 
    1266             : ZEND_BEGIN_ARG_INFO_EX(arginfo_gzgets, 0, 0, 1)
    1267             :         ZEND_ARG_INFO(0, fp)
    1268             :         ZEND_ARG_INFO(0, length)
    1269             : ZEND_END_ARG_INFO()
    1270             : 
    1271             : ZEND_BEGIN_ARG_INFO_EX(arginfo_deflate_init, 0, 0, 1)
    1272             :         ZEND_ARG_INFO(0, encoding)
    1273             :         ZEND_ARG_INFO(0, level)
    1274             : ZEND_END_ARG_INFO()
    1275             : 
    1276             : ZEND_BEGIN_ARG_INFO_EX(arginfo_deflate_add, 0, 0, 2)
    1277             :         ZEND_ARG_INFO(0, resource)
    1278             :         ZEND_ARG_INFO(0, add)
    1279             :         ZEND_ARG_INFO(0, flush_behavior)
    1280             : ZEND_END_ARG_INFO()
    1281             : 
    1282             : ZEND_BEGIN_ARG_INFO_EX(arginfo_inflate_init, 0, 0, 1)
    1283             :         ZEND_ARG_INFO(0, encoding)
    1284             : ZEND_END_ARG_INFO()
    1285             : 
    1286             : ZEND_BEGIN_ARG_INFO_EX(arginfo_inflate_add, 0, 0, 2)
    1287             :         ZEND_ARG_INFO(0, resource)
    1288             :         ZEND_ARG_INFO(0, flush_behavior)
    1289             : ZEND_END_ARG_INFO()
    1290             : 
    1291             : /* }}} */
    1292             : 
    1293             : /* {{{ php_zlib_functions[] */
    1294             : static const zend_function_entry php_zlib_functions[] = {
    1295             :         PHP_FE(readgzfile,                                              arginfo_readgzfile)
    1296             :         PHP_FALIAS(gzrewind,    rewind,                 arginfo_gzpassthru)
    1297             :         PHP_FALIAS(gzclose,             fclose,                 arginfo_gzpassthru)
    1298             :         PHP_FALIAS(gzeof,               feof,                   arginfo_gzpassthru)
    1299             :         PHP_FALIAS(gzgetc,              fgetc,                  arginfo_gzpassthru)
    1300             :         PHP_FALIAS(gzgets,              fgets,                  arginfo_gzgets)
    1301             :         PHP_FALIAS(gzgetss,             fgetss,                 arginfo_gzgetss)
    1302             :         PHP_FALIAS(gzread,              fread,                  arginfo_gzread)
    1303             :         PHP_FE(gzopen,                                                  arginfo_gzopen)
    1304             :         PHP_FALIAS(gzpassthru,  fpassthru,              arginfo_gzpassthru)
    1305             :         PHP_FALIAS(gzseek,              fseek,                  arginfo_gzseek)
    1306             :         PHP_FALIAS(gztell,              ftell,                  arginfo_gzpassthru)
    1307             :         PHP_FALIAS(gzwrite,             fwrite,                 arginfo_gzputs)
    1308             :         PHP_FALIAS(gzputs,              fwrite,                 arginfo_gzputs)
    1309             :         PHP_FE(gzfile,                                                  arginfo_gzfile)
    1310             :         PHP_FE(gzcompress,                                              arginfo_gzcompress)
    1311             :         PHP_FE(gzuncompress,                                    arginfo_gzuncompress)
    1312             :         PHP_FE(gzdeflate,                                               arginfo_gzdeflate)
    1313             :         PHP_FE(gzinflate,                                               arginfo_gzinflate)
    1314             :         PHP_FE(gzencode,                                                arginfo_gzencode)
    1315             :         PHP_FE(gzdecode,                                                arginfo_gzdecode)
    1316             :         PHP_FE(zlib_encode,                                             arginfo_zlib_encode)
    1317             :         PHP_FE(zlib_decode,                                             arginfo_zlib_decode)
    1318             :         PHP_FE(zlib_get_coding_type,                    arginfo_zlib_get_coding_type)
    1319             :         PHP_FE(deflate_init,                                    arginfo_deflate_init)
    1320             :         PHP_FE(deflate_add,                                             arginfo_deflate_add)
    1321             :         PHP_FE(inflate_init,                                    arginfo_inflate_init)
    1322             :         PHP_FE(inflate_add,                                             arginfo_inflate_add)
    1323             :         PHP_FE(ob_gzhandler,                                    arginfo_ob_gzhandler)
    1324             :         PHP_FE_END
    1325             : };
    1326             : /* }}} */
    1327             : 
    1328             : /* {{{ OnUpdate_zlib_output_compression */
    1329       21419 : static PHP_INI_MH(OnUpdate_zlib_output_compression)
    1330             : {
    1331             :         int int_value;
    1332             :         char *ini_value;
    1333             :         zend_long *p;
    1334             : #ifndef ZTS
    1335       21419 :         char *base = (char *) mh_arg2;
    1336             : #else
    1337             :         char *base;
    1338             : 
    1339             :         base = (char *) ts_resource(*((int *) mh_arg2));
    1340             : #endif
    1341             : 
    1342       21419 :         if (new_value == NULL) {
    1343           0 :                 return FAILURE;
    1344             :         }
    1345             : 
    1346       21419 :         if (!strncasecmp(new_value->val, "off", sizeof("off"))) {
    1347           0 :                 int_value = 0;
    1348       21419 :         } else if (!strncasecmp(new_value->val, "on", sizeof("on"))) {
    1349           0 :                 int_value = 1;
    1350             :         } else {
    1351       21419 :                 int_value = zend_atoi(new_value->val, new_value->len);
    1352             :         }
    1353       21419 :         ini_value = zend_ini_string("output_handler", sizeof("output_handler"), 0);
    1354             : 
    1355       21419 :         if (ini_value && *ini_value && int_value) {
    1356           0 :                 php_error_docref("ref.outcontrol", E_CORE_ERROR, "Cannot use both zlib.output_compression and output_handler together!!");
    1357           0 :                 return FAILURE;
    1358             :         }
    1359       21419 :         if (stage == PHP_INI_STAGE_RUNTIME) {
    1360         255 :                 int status = php_output_get_status();
    1361         255 :                 if (status & PHP_OUTPUT_SENT) {
    1362           0 :                         php_error_docref("ref.outcontrol", E_WARNING, "Cannot change zlib.output_compression - headers already sent");
    1363           0 :                         return FAILURE;
    1364             :                 }
    1365             :         }
    1366             : 
    1367       21419 :         p = (zend_long *) (base+(size_t) mh_arg1);
    1368       21419 :         *p = int_value;
    1369             : 
    1370       21419 :         ZLIBG(output_compression) = ZLIBG(output_compression_default);
    1371       21419 :         if (stage == PHP_INI_STAGE_RUNTIME && int_value) {
    1372           3 :                 if (!php_output_handler_started(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME))) {
    1373           3 :                         php_zlib_output_compression_start();
    1374             :                 }
    1375             :         }
    1376             : 
    1377       21419 :         return SUCCESS;
    1378             : }
    1379             : /* }}} */
    1380             : 
    1381             : /* {{{ OnUpdate_zlib_output_handler */
    1382       20916 : static PHP_INI_MH(OnUpdate_zlib_output_handler)
    1383             : {
    1384       20916 :         if (stage == PHP_INI_STAGE_RUNTIME && (php_output_get_status() & PHP_OUTPUT_SENT)) {
    1385           0 :                 php_error_docref("ref.outcontrol", E_WARNING, "Cannot change zlib.output_handler - headers already sent");
    1386           0 :                 return FAILURE;
    1387             :         }
    1388             : 
    1389       20916 :         return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
    1390             : }
    1391             : /* }}} */
    1392             : 
    1393             : /* {{{ INI */
    1394             : PHP_INI_BEGIN()
    1395             :         STD_PHP_INI_BOOLEAN("zlib.output_compression",      "0", PHP_INI_ALL, OnUpdate_zlib_output_compression,       output_compression_default,       zend_zlib_globals, zlib_globals)
    1396             :         STD_PHP_INI_ENTRY("zlib.output_compression_level", "-1", PHP_INI_ALL, OnUpdateLong,                           output_compression_level, zend_zlib_globals, zlib_globals)
    1397             :         STD_PHP_INI_ENTRY("zlib.output_handler",             "", PHP_INI_ALL, OnUpdate_zlib_output_handler,           output_handler,           zend_zlib_globals, zlib_globals)
    1398             : PHP_INI_END()
    1399             : 
    1400             : /* }}} */
    1401             : 
    1402             : /* {{{ PHP_MINIT_FUNCTION */
    1403       20916 : static PHP_MINIT_FUNCTION(zlib)
    1404             : {
    1405       20916 :         php_register_url_stream_wrapper("compress.zlib", &php_stream_gzip_wrapper);
    1406       20916 :         php_stream_filter_register_factory("zlib.*", &php_zlib_filter_factory);
    1407             : 
    1408       20916 :         php_output_handler_alias_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_handler_init);
    1409       20916 :         php_output_handler_conflict_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_conflict_check);
    1410       20916 :         php_output_handler_conflict_register(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), php_zlib_output_conflict_check);
    1411             : 
    1412       20916 :         le_deflate = zend_register_list_destructors_ex(deflate_rsrc_dtor, NULL, "zlib.deflate", module_number);
    1413       20916 :         le_inflate = zend_register_list_destructors_ex(inflate_rsrc_dtor, NULL, "zlib.inflate", module_number);
    1414             : 
    1415       20916 :         REGISTER_LONG_CONSTANT("FORCE_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
    1416       20916 :         REGISTER_LONG_CONSTANT("FORCE_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
    1417             : 
    1418       20916 :         REGISTER_LONG_CONSTANT("ZLIB_ENCODING_RAW", PHP_ZLIB_ENCODING_RAW, CONST_CS|CONST_PERSISTENT);
    1419       20916 :         REGISTER_LONG_CONSTANT("ZLIB_ENCODING_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
    1420       20916 :         REGISTER_LONG_CONSTANT("ZLIB_ENCODING_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
    1421             : 
    1422       20916 :         REGISTER_LONG_CONSTANT("ZLIB_NO_FLUSH", Z_NO_FLUSH, CONST_CS|CONST_PERSISTENT);
    1423       20916 :         REGISTER_LONG_CONSTANT("ZLIB_PARTIAL_FLUSH", Z_PARTIAL_FLUSH, CONST_CS|CONST_PERSISTENT);
    1424       20916 :         REGISTER_LONG_CONSTANT("ZLIB_SYNC_FLUSH", Z_SYNC_FLUSH, CONST_CS|CONST_PERSISTENT);
    1425       20916 :         REGISTER_LONG_CONSTANT("ZLIB_FULL_FLUSH", Z_FULL_FLUSH, CONST_CS|CONST_PERSISTENT);
    1426       20916 :         REGISTER_LONG_CONSTANT("ZLIB_BLOCK", Z_BLOCK, CONST_CS|CONST_PERSISTENT);
    1427       20916 :         REGISTER_LONG_CONSTANT("ZLIB_FINISH", Z_FINISH, CONST_CS|CONST_PERSISTENT);
    1428             : 
    1429       20916 :         REGISTER_LONG_CONSTANT("ZLIB_FILTERED", Z_FILTERED, CONST_CS|CONST_PERSISTENT);
    1430       20916 :         REGISTER_LONG_CONSTANT("ZLIB_HUFFMAN_ONLY", Z_HUFFMAN_ONLY, CONST_CS|CONST_PERSISTENT);
    1431       20916 :         REGISTER_LONG_CONSTANT("ZLIB_RLE", Z_RLE, CONST_CS|CONST_PERSISTENT);
    1432       20916 :         REGISTER_LONG_CONSTANT("ZLIB_FIXED", Z_FIXED, CONST_CS|CONST_PERSISTENT);
    1433       20916 :         REGISTER_LONG_CONSTANT("ZLIB_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY, CONST_CS|CONST_PERSISTENT);
    1434             : 
    1435       20916 :         REGISTER_STRING_CONSTANT("ZLIB_VERSION", ZLIB_VERSION, CONST_CS|CONST_PERSISTENT);
    1436       20916 :         REGISTER_LONG_CONSTANT("ZLIB_VERNUM", ZLIB_VERNUM, CONST_CS|CONST_PERSISTENT);
    1437             : 
    1438       20916 :         REGISTER_INI_ENTRIES();
    1439       20916 :         return SUCCESS;
    1440             : }
    1441             : /* }}} */
    1442             : 
    1443             : /* {{{ PHP_MSHUTDOWN_FUNCTION */
    1444       20952 : static PHP_MSHUTDOWN_FUNCTION(zlib)
    1445             : {
    1446       20952 :         php_unregister_url_stream_wrapper("zlib");
    1447       20952 :         php_stream_filter_unregister_factory("zlib.*");
    1448             : 
    1449       20952 :         UNREGISTER_INI_ENTRIES();
    1450             : 
    1451       20952 :         return SUCCESS;
    1452             : }
    1453             : /* }}} */
    1454             : 
    1455             : /* {{{ PHP_RINIT_FUNCTION */
    1456       20873 : static PHP_RINIT_FUNCTION(zlib)
    1457             : {
    1458       20873 :         ZLIBG(compression_coding) = 0;
    1459       20873 :     if (!ZLIBG(handler_registered)) {
    1460       20870 :         ZLIBG(output_compression) = ZLIBG(output_compression_default);
    1461       20870 :         php_zlib_output_compression_start();
    1462             :     }
    1463             : 
    1464       20873 :         return SUCCESS;
    1465             : }
    1466             : /* }}} */
    1467             : 
    1468             : /* {{{ PHP_RSHUTDOWN_FUNCTION */
    1469       20911 : static PHP_RSHUTDOWN_FUNCTION(zlib)
    1470             : {
    1471       20911 :         php_zlib_cleanup_ob_gzhandler_mess();
    1472       20911 :     ZLIBG(handler_registered) = 0;
    1473             : 
    1474       20911 :     return SUCCESS;
    1475             : }
    1476             : /* }}} */
    1477             : 
    1478             : /* {{{ PHP_MINFO_FUNCTION */
    1479         142 : static PHP_MINFO_FUNCTION(zlib)
    1480             : {
    1481         142 :         php_info_print_table_start();
    1482         142 :         php_info_print_table_header(2, "ZLib Support", "enabled");
    1483         142 :         php_info_print_table_row(2, "Stream Wrapper", "compress.zlib://");
    1484         142 :         php_info_print_table_row(2, "Stream Filter", "zlib.inflate, zlib.deflate");
    1485         142 :         php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION);
    1486         142 :         php_info_print_table_row(2, "Linked Version", (char *) zlibVersion());
    1487         142 :         php_info_print_table_end();
    1488             : 
    1489         142 :         DISPLAY_INI_ENTRIES();
    1490         142 : }
    1491             : /* }}} */
    1492             : 
    1493             : /* {{{ ZEND_MODULE_GLOBALS_CTOR */
    1494       20916 : static PHP_GINIT_FUNCTION(zlib)
    1495             : {
    1496             : #if defined(COMPILE_DL_ZLIB) && defined(ZTS)
    1497             :         ZEND_TSRMLS_CACHE_UPDATE();
    1498             : #endif
    1499       20916 :         zlib_globals->ob_gzhandler = NULL;
    1500       20916 :     zlib_globals->handler_registered = 0;
    1501       20916 : }
    1502             : /* }}} */
    1503             : 
    1504             : /* {{{ php_zlib_module_entry */
    1505             : zend_module_entry php_zlib_module_entry = {
    1506             :         STANDARD_MODULE_HEADER,
    1507             :         "zlib",
    1508             :         php_zlib_functions,
    1509             :         PHP_MINIT(zlib),
    1510             :         PHP_MSHUTDOWN(zlib),
    1511             :         PHP_RINIT(zlib),
    1512             :         PHP_RSHUTDOWN(zlib),
    1513             :         PHP_MINFO(zlib),
    1514             :         PHP_ZLIB_VERSION,
    1515             :         PHP_MODULE_GLOBALS(zlib),
    1516             :         PHP_GINIT(zlib),
    1517             :         NULL,
    1518             :         NULL,
    1519             :         STANDARD_MODULE_PROPERTIES_EX
    1520             : };
    1521             : /* }}} */
    1522             : 
    1523             : /*
    1524             :  * Local variables:
    1525             :  * tab-width: 4
    1526             :  * c-basic-offset: 4
    1527             :  * End:
    1528             :  * vim600: sw=4 ts=4 fdm=marker
    1529             :  * vim<600: sw=4 ts=4
    1530             :  */

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:59:07 +0000 (6 days ago)

Copyright © 2005-2015 The PHP Group
All rights reserved.