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: 555 687 80.8 %
Date: 2019-05-06 Functions: 44 44 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 06 May 2019 17:58:31 +0000 (166 days ago)

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