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

Generated by: LCOV version 1.10

Generated at Sat, 29 Aug 2015 10:22:27 +0000 (2 days ago)

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