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: 488 605 80.7 %
Date: 2015-07-26 Functions: 41 42 97.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 27 Jul 2015 02:32:30 +0000 (2 days ago)

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