root/ext/zlib/zlib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_zlib_alloc
  2. php_zlib_free
  3. deflate_rsrc_dtor
  4. inflate_rsrc_dtor
  5. php_zlib_output_conflict_check
  6. php_zlib_output_encoding
  7. php_zlib_output_handler_ex
  8. php_zlib_output_handler
  9. php_zlib_output_handler_context_init
  10. php_zlib_output_handler_context_dtor
  11. php_zlib_output_handler_init
  12. php_zlib_output_compression_start
  13. php_zlib_encode
  14. php_zlib_inflate_rounds
  15. php_zlib_decode
  16. php_zlib_cleanup_ob_gzhandler_mess
  17. PHP_FUNCTION
  18. PHP_FUNCTION
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. zlib_create_dictionary_string
  23. PHP_FUNCTION
  24. PHP_FUNCTION
  25. PHP_FUNCTION
  26. PHP_FUNCTION
  27. PHP_INI_MH
  28. PHP_INI_MH
  29. PHP_INI_BEGIN
  30. PHP_MSHUTDOWN_FUNCTION
  31. PHP_RINIT_FUNCTION
  32. PHP_RSHUTDOWN_FUNCTION
  33. PHP_MINFO_FUNCTION
  34. PHP_GINIT_FUNCTION

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 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 static voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size)
  57 {
  58         return (voidpf)safe_emalloc(items, size, 0);
  59 }
  60 
  61 static void php_zlib_free(voidpf opaque, voidpf address)
  62 {
  63         efree((void*)address);
  64 }
  65 /* }}} */
  66 
  67 /* {{{ Incremental deflate/inflate resource destructors */
  68 
  69 void deflate_rsrc_dtor(zend_resource *res)
  70 {
  71         z_stream *ctx = zend_fetch_resource(res, NULL, le_deflate);
  72         deflateEnd(ctx);
  73         efree(ctx);
  74 }
  75 
  76 void inflate_rsrc_dtor(zend_resource *res)
  77 {
  78         z_stream *ctx = zend_fetch_resource(res, NULL, le_inflate);
  79         if (((php_zlib_context *) ctx)->inflateDict) {
  80                 efree(((php_zlib_context *) ctx)->inflateDict);
  81         }
  82         inflateEnd(ctx);
  83         efree(ctx);
  84 }
  85 
  86 /* }}} */
  87 
  88 /* {{{ php_zlib_output_conflict_check() */
  89 static int php_zlib_output_conflict_check(const char *handler_name, size_t handler_name_len)
  90 {
  91         if (php_output_get_level() > 0) {
  92                 if (php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME))
  93                 ||      php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("ob_gzhandler"))
  94                 ||  php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("mb_output_handler"))
  95                 ||      php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("URL-Rewriter"))) {
  96                         return FAILURE;
  97                 }
  98         }
  99         return SUCCESS;
 100 }
 101 /* }}} */
 102 
 103 /* {{{ php_zlib_output_encoding() */
 104 static int php_zlib_output_encoding(void)
 105 {
 106         zval *enc;
 107 
 108         if (!ZLIBG(compression_coding)) {
 109                 if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
 110                         (enc = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING") - 1))) {
 111                         convert_to_string(enc);
 112                         if (strstr(Z_STRVAL_P(enc), "gzip")) {
 113                                 ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_GZIP;
 114                         } else if (strstr(Z_STRVAL_P(enc), "deflate")) {
 115                                 ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_DEFLATE;
 116                         }
 117                 }
 118         }
 119         return ZLIBG(compression_coding);
 120 }
 121 /* }}} */
 122 
 123 /* {{{ php_zlib_output_handler_ex() */
 124 static int php_zlib_output_handler_ex(php_zlib_context *ctx, php_output_context *output_context)
 125 {
 126         int flags = Z_SYNC_FLUSH;
 127 
 128         if (output_context->op & PHP_OUTPUT_HANDLER_START) {
 129                 /* start up */
 130                 if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) {
 131                         return FAILURE;
 132                 }
 133         }
 134 
 135         if (output_context->op & PHP_OUTPUT_HANDLER_CLEAN) {
 136                 /* free buffers */
 137                 deflateEnd(&ctx->Z);
 138 
 139                 if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
 140                         /* discard */
 141                         return SUCCESS;
 142                 } else {
 143                         /* restart */
 144                         if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) {
 145                                 return FAILURE;
 146                         }
 147                         ctx->buffer.used = 0;
 148                 }
 149         } else {
 150                 if (output_context->in.used) {
 151                         /* append input */
 152                         if (ctx->buffer.free < output_context->in.used) {
 153                                 if (!(ctx->buffer.aptr = erealloc_recoverable(ctx->buffer.data, ctx->buffer.used + ctx->buffer.free + output_context->in.used))) {
 154                                         deflateEnd(&ctx->Z);
 155                                         return FAILURE;
 156                                 }
 157                                 ctx->buffer.data = ctx->buffer.aptr;
 158                                 ctx->buffer.free += output_context->in.used;
 159                         }
 160                         memcpy(ctx->buffer.data + ctx->buffer.used, output_context->in.data, output_context->in.used);
 161                         ctx->buffer.free -= output_context->in.used;
 162                         ctx->buffer.used += output_context->in.used;
 163                 }
 164                 output_context->out.size = PHP_ZLIB_BUFFER_SIZE_GUESS(output_context->in.used);
 165                 output_context->out.data = emalloc(output_context->out.size);
 166                 output_context->out.free = 1;
 167                 output_context->out.used = 0;
 168 
 169                 ctx->Z.avail_in = ctx->buffer.used;
 170                 ctx->Z.next_in = (Bytef *) ctx->buffer.data;
 171                 ctx->Z.avail_out = output_context->out.size;
 172                 ctx->Z.next_out = (Bytef *) output_context->out.data;
 173 
 174                 if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
 175                         flags = Z_FINISH;
 176                 } else if (output_context->op & PHP_OUTPUT_HANDLER_FLUSH) {
 177                         flags = Z_FULL_FLUSH;
 178                 }
 179 
 180                 switch (deflate(&ctx->Z, flags)) {
 181                         case Z_OK:
 182                                 if (flags == Z_FINISH) {
 183                                         deflateEnd(&ctx->Z);
 184                                         return FAILURE;
 185                                 }
 186                         case Z_STREAM_END:
 187                                 if (ctx->Z.avail_in) {
 188                                         memmove(ctx->buffer.data, ctx->buffer.data + ctx->buffer.used - ctx->Z.avail_in, ctx->Z.avail_in);
 189                                 }
 190                                 ctx->buffer.free += ctx->buffer.used - ctx->Z.avail_in;
 191                                 ctx->buffer.used = ctx->Z.avail_in;
 192                                 output_context->out.used = output_context->out.size - ctx->Z.avail_out;
 193                                 break;
 194                         default:
 195                                 deflateEnd(&ctx->Z);
 196                                 return FAILURE;
 197                 }
 198 
 199                 if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
 200                         deflateEnd(&ctx->Z);
 201                 }
 202         }
 203 
 204         return SUCCESS;
 205 }
 206 /* }}} */
 207 
 208 /* {{{ php_zlib_output_handler() */
 209 static int php_zlib_output_handler(void **handler_context, php_output_context *output_context)
 210 {
 211         php_zlib_context *ctx = *(php_zlib_context **) handler_context;
 212 
 213         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                 if ((output_context->op & PHP_OUTPUT_HANDLER_START)
 225                 &&      (output_context->op != (PHP_OUTPUT_HANDLER_START|PHP_OUTPUT_HANDLER_CLEAN|PHP_OUTPUT_HANDLER_FINAL))
 226                 ) {
 227                         sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 0);
 228                 }
 229                 return FAILURE;
 230         }
 231 
 232         if (SUCCESS != php_zlib_output_handler_ex(ctx, output_context)) {
 233                 return FAILURE;
 234         }
 235 
 236         if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) {
 237                 int flags;
 238 
 239                 if (SUCCESS == php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS, &flags)) {
 240                         /* only run this once */
 241                         if (!(flags & PHP_OUTPUT_HANDLER_STARTED)) {
 242                                 if (SG(headers_sent) || !ZLIBG(output_compression)) {
 243                                         deflateEnd(&ctx->Z);
 244                                         return FAILURE;
 245                                 }
 246                                 switch (ZLIBG(compression_coding)) {
 247                                         case PHP_ZLIB_ENCODING_GZIP:
 248                                                 sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1);
 249                                                 break;
 250                                         case PHP_ZLIB_ENCODING_DEFLATE:
 251                                                 sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1);
 252                                                 break;
 253                                         default:
 254                                                 deflateEnd(&ctx->Z);
 255                                                 return FAILURE;
 256                                 }
 257                                 sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 0);
 258                                 php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL);
 259                         }
 260                 }
 261         }
 262 
 263         return SUCCESS;
 264 }
 265 /* }}} */
 266 
 267 /* {{{ php_zlib_output_handler_context_init() */
 268 static php_zlib_context *php_zlib_output_handler_context_init(void)
 269 {
 270         php_zlib_context *ctx = (php_zlib_context *) ecalloc(1, sizeof(php_zlib_context));
 271         ctx->Z.zalloc = php_zlib_alloc;
 272         ctx->Z.zfree = php_zlib_free;
 273         return ctx;
 274 }
 275 /* }}} */
 276 
 277 /* {{{ php_zlib_output_handler_context_dtor() */
 278 static void php_zlib_output_handler_context_dtor(void *opaq)
 279 {
 280         php_zlib_context *ctx = (php_zlib_context *) opaq;
 281 
 282         if (ctx) {
 283                 if (ctx->buffer.data) {
 284                         efree(ctx->buffer.data);
 285                 }
 286                 efree(ctx);
 287         }
 288 }
 289 /* }}} */
 290 
 291 /* {{{ php_zlib_output_handler_init() */
 292 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         php_output_handler *h = NULL;
 295 
 296         if (!ZLIBG(output_compression)) {
 297                 ZLIBG(output_compression) = chunk_size ? chunk_size : PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
 298         }
 299 
 300     ZLIBG(handler_registered) = 1;
 301 
 302         if ((h = php_output_handler_create_internal(handler_name, handler_name_len, php_zlib_output_handler, chunk_size, flags))) {
 303                 php_output_handler_set_context(h, php_zlib_output_handler_context_init(), php_zlib_output_handler_context_dtor);
 304         }
 305 
 306         return h;
 307 }
 308 /* }}} */
 309 
 310 /* {{{ php_zlib_output_compression_start() */
 311 static void php_zlib_output_compression_start(void)
 312 {
 313         zval zoh;
 314         php_output_handler *h;
 315 
 316         switch (ZLIBG(output_compression)) {
 317                 case 0:
 318                         break;
 319                 case 1:
 320                         ZLIBG(output_compression) = PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
 321                         /* break omitted intentionally */
 322                 default:
 323                         if (    php_zlib_output_encoding() &&
 324                                         (h = php_zlib_output_handler_init(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS)) &&
 325                                         (SUCCESS == php_output_handler_start(h))) {
 326                                 if (ZLIBG(output_handler) && *ZLIBG(output_handler)) {
 327                                         ZVAL_STRING(&zoh, ZLIBG(output_handler));
 328                                         php_output_start_user(&zoh, ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS);
 329                                         zval_ptr_dtor(&zoh);
 330                                 }
 331                         }
 332                         break;
 333         }
 334 }
 335 /* }}} */
 336 
 337 /* {{{ php_zlib_encode() */
 338 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         memset(&Z, 0, sizeof(z_stream));
 345         Z.zalloc = php_zlib_alloc;
 346         Z.zfree = php_zlib_free;
 347 
 348         if (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, encoding, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) {
 349                 out = zend_string_alloc(PHP_ZLIB_BUFFER_SIZE_GUESS(in_len), 0);
 350 
 351                 Z.next_in = (Bytef *) in_buf;
 352                 Z.next_out = (Bytef *) ZSTR_VAL(out);
 353                 Z.avail_in = in_len;
 354                 Z.avail_out = ZSTR_LEN(out);
 355 
 356                 status = deflate(&Z, Z_FINISH);
 357                 deflateEnd(&Z);
 358 
 359                 if (Z_STREAM_END == status) {
 360                         /* size buffer down to actual length */
 361                         out = zend_string_truncate(out, Z.total_out, 0);
 362                         ZSTR_VAL(out)[ZSTR_LEN(out)] = '\0';
 363                         return out;
 364                 } else {
 365                         zend_string_free(out);
 366                 }
 367         }
 368 
 369         php_error_docref(NULL, E_WARNING, "%s", zError(status));
 370         return NULL;
 371 }
 372 /* }}} */
 373 
 374 /* {{{ php_zlib_inflate_rounds() */
 375 static inline int php_zlib_inflate_rounds(z_stream *Z, size_t max, char **buf, size_t *len)
 376 {
 377         int status, round = 0;
 378         php_zlib_buffer buffer = {NULL, NULL, 0, 0, 0};
 379 
 380         *buf = NULL;
 381         *len = 0;
 382 
 383         buffer.size = (max && (max < Z->avail_in)) ? max : Z->avail_in;
 384 
 385         do {
 386                 if ((max && (max <= buffer.used)) || !(buffer.aptr = erealloc_recoverable(buffer.data, buffer.size))) {
 387                         status = Z_MEM_ERROR;
 388                 } else {
 389                         buffer.data = buffer.aptr;
 390                         Z->avail_out = buffer.free = buffer.size - buffer.used;
 391                         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                         status = inflate(Z, Z_NO_FLUSH);
 396 
 397                         buffer.used += buffer.free - Z->avail_out;
 398                         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                         buffer.size += (buffer.size >> 3) + 1;
 403                 }
 404         } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < 100);
 405 
 406         if (status == Z_STREAM_END) {
 407                 buffer.data = erealloc(buffer.data, buffer.used + 1);
 408                 buffer.data[buffer.used] = '\0';
 409                 *buf = buffer.data;
 410                 *len = buffer.used;
 411         } else {
 412                 if (buffer.data) {
 413                         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                 status = (status == Z_OK) ? Z_DATA_ERROR : status;
 418         }
 419         return status;
 420 }
 421 /* }}} */
 422 
 423 /* {{{ php_zlib_decode() */
 424 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         int status = Z_DATA_ERROR;
 427         z_stream Z;
 428 
 429         memset(&Z, 0, sizeof(z_stream));
 430         Z.zalloc = php_zlib_alloc;
 431         Z.zfree = php_zlib_free;
 432 
 433         if (in_len) {
 434 retry_raw_inflate:
 435                 status = inflateInit2(&Z, encoding);
 436                 if (Z_OK == status) {
 437                         Z.next_in = (Bytef *) in_buf;
 438                         Z.avail_in = in_len + 1; /* NOTE: data must be zero terminated */
 439 
 440                         switch (status = php_zlib_inflate_rounds(&Z, max_len, out_buf, out_len)) {
 441                                 case Z_STREAM_END:
 442                                         inflateEnd(&Z);
 443                                         return SUCCESS;
 444 
 445                                 case Z_DATA_ERROR:
 446                                         /* raw deflated data? */
 447                                         if (PHP_ZLIB_ENCODING_ANY == encoding) {
 448                                                 inflateEnd(&Z);
 449                                                 encoding = PHP_ZLIB_ENCODING_RAW;
 450                                                 goto retry_raw_inflate;
 451                                         }
 452                         }
 453                         inflateEnd(&Z);
 454                 }
 455         }
 456 
 457         *out_buf = NULL;
 458         *out_len = 0;
 459 
 460         php_error_docref(NULL, E_WARNING, "%s", zError(status));
 461         return FAILURE;
 462 }
 463 /* }}} */
 464 
 465 /* {{{ php_zlib_cleanup_ob_gzhandler_mess() */
 466 static void php_zlib_cleanup_ob_gzhandler_mess(void)
 467 {
 468         if (ZLIBG(ob_gzhandler)) {
 469                 deflateEnd(&(ZLIBG(ob_gzhandler)->Z));
 470                 php_zlib_output_handler_context_dtor(ZLIBG(ob_gzhandler));
 471                 ZLIBG(ob_gzhandler) = NULL;
 472         }
 473 }
 474 /* }}} */
 475 
 476 /* {{{ proto string ob_gzhandler(string data, int flags)
 477    Legacy hack */
 478 static PHP_FUNCTION(ob_gzhandler)
 479 {
 480         char *in_str;
 481         size_t in_len;
 482         zend_long flags = 0;
 483         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         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "sl", &in_str, &in_len, &flags)) {
 495                 RETURN_FALSE;
 496         }
 497 
 498         if (!(encoding = php_zlib_output_encoding())) {
 499                 RETURN_FALSE;
 500         }
 501 
 502         if (flags & PHP_OUTPUT_HANDLER_START) {
 503                 switch (encoding) {
 504                         case PHP_ZLIB_ENCODING_GZIP:
 505                                 sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1);
 506                                 break;
 507                         case PHP_ZLIB_ENCODING_DEFLATE:
 508                                 sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1);
 509                                 break;
 510                 }
 511                 sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 0);
 512         }
 513 
 514         if (!ZLIBG(ob_gzhandler)) {
 515                 ZLIBG(ob_gzhandler) = php_zlib_output_handler_context_init();
 516         }
 517 
 518         ctx.op = flags;
 519         ctx.in.data = in_str;
 520         ctx.in.used = in_len;
 521 
 522         rv = php_zlib_output_handler_ex(ZLIBG(ob_gzhandler), &ctx);
 523 
 524         if (SUCCESS != rv) {
 525                 if (ctx.out.data && ctx.out.free) {
 526                         efree(ctx.out.data);
 527                 }
 528                 php_zlib_cleanup_ob_gzhandler_mess();
 529                 RETURN_FALSE;
 530         }
 531 
 532         if (ctx.out.data) {
 533                 RETVAL_STRINGL(ctx.out.data, ctx.out.used);
 534                 if (ctx.out.free) {
 535                         efree(ctx.out.data);
 536                 }
 537         } else {
 538                 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 static PHP_FUNCTION(zlib_get_coding_type)
 546 {
 547         if (zend_parse_parameters_none() == FAILURE) {
 548                 return;
 549         }
 550         switch (ZLIBG(compression_coding)) {
 551                 case PHP_ZLIB_ENCODING_GZIP:
 552                         RETURN_STRINGL("gzip", sizeof("gzip") - 1);
 553                 case PHP_ZLIB_ENCODING_DEFLATE:
 554                         RETURN_STRINGL("deflate", sizeof("deflate") - 1);
 555                 default:
 556                         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 static PHP_FUNCTION(gzfile)
 564 {
 565         char *filename;
 566         size_t filename_len;
 567         int flags = REPORT_ERRORS;
 568         char buf[8192] = {0};
 569         register int i = 0;
 570         zend_long use_include_path = 0;
 571         php_stream *stream;
 572 
 573         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &filename, &filename_len, &use_include_path)) {
 574                 return;
 575         }
 576 
 577         if (use_include_path) {
 578                 flags |= USE_PATH;
 579         }
 580 
 581         /* using a stream here is a bit more efficient (resource wise) than php_gzopen_wrapper */
 582         stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC);
 583 
 584         if (!stream) {
 585                 /* Error reporting is already done by stream code */
 586                 RETURN_FALSE;
 587         }
 588 
 589         /* Initialize return array */
 590         array_init(return_value);
 591 
 592         /* Now loop through the file and do the magic quotes thing if needed */
 593         memset(buf, 0, sizeof(buf));
 594 
 595         while (php_stream_gets(stream, buf, sizeof(buf) - 1) != NULL) {
 596                 add_index_string(return_value, i++, buf);
 597         }
 598         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 static PHP_FUNCTION(gzopen)
 605 {
 606         char *filename;
 607         char *mode;
 608         size_t filename_len, mode_len;
 609         int flags = REPORT_ERRORS;
 610         php_stream *stream;
 611         zend_long use_include_path = 0;
 612 
 613         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ps|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) {
 614                 return;
 615         }
 616 
 617         if (use_include_path) {
 618                 flags |= USE_PATH;
 619         }
 620 
 621         stream = php_stream_gzopen(NULL, filename, mode, flags, NULL, NULL STREAMS_CC);
 622 
 623         if (!stream) {
 624                 RETURN_FALSE;
 625         }
 626         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 static PHP_FUNCTION(readgzfile)
 633 {
 634         char *filename;
 635         size_t filename_len;
 636         int flags = REPORT_ERRORS;
 637         php_stream *stream;
 638         size_t size;
 639         zend_long use_include_path = 0;
 640 
 641         if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &filename, &filename_len, &use_include_path) == FAILURE) {
 642                 return;
 643         }
 644 
 645         if (use_include_path) {
 646                 flags |= USE_PATH;
 647         }
 648 
 649         stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC);
 650 
 651         if (!stream) {
 652                 RETURN_FALSE;
 653         }
 654         size = php_stream_passthru(stream);
 655         php_stream_close(stream);
 656         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 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 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 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 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 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 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 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 PHP_ZLIB_DECODE_FUNC(gzuncompress, PHP_ZLIB_ENCODING_DEFLATE);
 754 /* }}} */
 755 
 756 static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, size_t *dictlen) {
 757         zval *option_buffer;
 758 
 759         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("dictionary"))) != NULL) {
 760                 ZVAL_DEREF(option_buffer);
 761                 switch (Z_TYPE_P(option_buffer)) {
 762                         case IS_STRING: {
 763                                 zend_string *str = Z_STR_P(option_buffer);
 764                                 int i;
 765                                 zend_bool last_null = 1;
 766 
 767                                 for (i = 0; i < ZSTR_LEN(str); i++) {
 768                                         if (ZSTR_VAL(str)[i]) {
 769                                                 last_null = 0;
 770                                         } else {
 771                                                 if (last_null) {
 772                                                         php_error_docref(NULL, E_WARNING, "dictionary string must not contain empty entries (two consecutive NULL-bytes or one at the very beginning)");
 773                                                         return 0;
 774                                                 }
 775                                                 last_null = 1;
 776                                         }
 777                                 }
 778                                 if (!last_null) {
 779                                         php_error_docref(NULL, E_WARNING, "dictionary string must be NULL-byte terminated (each dictionary entry has to be NULL-terminated)");
 780                                 }
 781 
 782                                 *dict = emalloc(ZSTR_LEN(str));
 783                                 memcpy(*dict, ZSTR_VAL(str), ZSTR_LEN(str));
 784                                 *dictlen = ZSTR_LEN(str);
 785                         } break;
 786 
 787                         case IS_ARRAY: {
 788                                 HashTable *dictionary = Z_ARR_P(option_buffer);
 789 
 790                                 if (zend_hash_num_elements(dictionary) > 0) {
 791                                         char *dictptr;
 792                                         zval *cur;
 793                                         zend_string **strings = emalloc(sizeof(zend_string *) * zend_hash_num_elements(dictionary));
 794                                         zend_string **end, **ptr = strings - 1;
 795 
 796                                         ZEND_HASH_FOREACH_VAL(dictionary, cur) {
 797                                                 int i;
 798 
 799                                                 *++ptr = zval_get_string(cur);
 800                                                 if (!*ptr || ZSTR_LEN(*ptr) == 0) {
 801                                                         if (*ptr) {
 802                                                                 efree(*ptr);
 803                                                         }
 804                                                         while (--ptr >= strings) {
 805                                                                 efree(ptr);
 806                                                         }
 807                                                         efree(strings);
 808                                                         php_error_docref(NULL, E_WARNING, "dictionary entries must be non-empty strings");
 809                                                         return 0;
 810                                                 }
 811                                                 for (i = 0; i < ZSTR_LEN(*ptr); i++) {
 812                                                         if (ZSTR_VAL(*ptr)[i] == 0) {
 813                                                                 do {
 814                                                                         efree(ptr);
 815                                                                 } while (--ptr >= strings);
 816                                                                 efree(strings);
 817                                                                 php_error_docref(NULL, E_WARNING, "dictionary entries must not contain a NULL-byte");
 818                                                                 return 0;
 819                                                         }
 820                                                 }
 821 
 822                                                 *dictlen += ZSTR_LEN(*ptr) + 1;
 823                                         } ZEND_HASH_FOREACH_END();
 824 
 825                                         dictptr = *dict = emalloc(*dictlen);
 826                                         ptr = strings;
 827                                         end = strings + zend_hash_num_elements(dictionary);
 828                                         do {
 829                                                 memcpy(dictptr, ZSTR_VAL(*ptr), ZSTR_LEN(*ptr));
 830                                                 dictptr += ZSTR_LEN(*ptr);
 831                                                 *dictptr++ = 0;
 832                                                 zend_string_release(*ptr);
 833                                         } while (++ptr != end);
 834                                         efree(strings);
 835                                 }
 836                         } break;
 837 
 838                         default:
 839                                 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                                 return 0;
 841                 }
 842         }
 843 
 844         return 1;
 845 }
 846 
 847 /* {{{ proto resource inflate_init(int encoding)
 848    Initialize an incremental inflate context with the specified encoding */
 849 PHP_FUNCTION(inflate_init)
 850 {
 851         z_stream *ctx;
 852         zend_long encoding, window = 15;
 853         char *dict = NULL;
 854         size_t dictlen = 0;
 855         HashTable *options = NULL;
 856         zval *option_buffer;
 857 
 858         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) {
 859                 return;
 860         }
 861 
 862         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) {
 863                 window = zval_get_long(option_buffer);
 864         }
 865         if (window < 8 || window > 15) {
 866                 php_error_docref(NULL, E_WARNING, "zlib window size (lograithm) (%pd) must be within 8..15", window);
 867                 RETURN_FALSE;
 868         }
 869 
 870         if (!zlib_create_dictionary_string(options, &dict, &dictlen)) {
 871                 RETURN_FALSE;
 872         }
 873 
 874         switch (encoding) {
 875                 case PHP_ZLIB_ENCODING_RAW:
 876                 case PHP_ZLIB_ENCODING_GZIP:
 877                 case PHP_ZLIB_ENCODING_DEFLATE:
 878                         break;
 879                 default:
 880                         php_error_docref(NULL, E_WARNING, "encoding mode must be ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE");
 881                         RETURN_FALSE;
 882         }
 883 
 884         ctx = ecalloc(1, sizeof(php_zlib_context));
 885         ctx->zalloc = php_zlib_alloc;
 886         ctx->zfree = php_zlib_free;
 887         ((php_zlib_context *) ctx)->inflateDict = dict;
 888         ((php_zlib_context *) ctx)->inflateDictlen = dictlen;
 889 
 890         if (encoding < 0) {
 891                 encoding += 15 - window;
 892         } else {
 893                 encoding -= 15 - window;
 894         }
 895 
 896         if (Z_OK == inflateInit2(ctx, encoding)) {
 897                 RETURN_RES(zend_register_resource(ctx, le_inflate));
 898         } else {
 899                 efree(ctx);
 900                 php_error_docref(NULL, E_WARNING, "failed allocating zlib.inflate context");
 901                 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 PHP_FUNCTION(inflate_add)
 909 {
 910         zend_string *out;
 911         char *in_buf;
 912         size_t in_len, buffer_used = 0, CHUNK_SIZE = 8192;
 913         zval *res;
 914         z_stream *ctx;
 915         zend_long flush_type = Z_SYNC_FLUSH;
 916         int status;
 917 
 918         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &res, &in_buf, &in_len, &flush_type)) {
 919                 return;
 920         }
 921 
 922         if (!(ctx = zend_fetch_resource_ex(res, NULL, le_inflate))) {
 923                 php_error_docref(NULL, E_WARNING, "Invalid zlib.inflate resource");
 924                 RETURN_FALSE;
 925         }
 926 
 927         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                         break;
 935 
 936                 default:
 937                         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                         RETURN_FALSE;
 940         }
 941 
 942         if (in_len <= 0 && flush_type != Z_FINISH) {
 943                 RETURN_EMPTY_STRING();
 944         }
 945 
 946         out = zend_string_alloc((in_len > CHUNK_SIZE) ? in_len : CHUNK_SIZE, 0);
 947         ctx->next_in = (Bytef *) in_buf;
 948         ctx->next_out = (Bytef *) ZSTR_VAL(out);
 949         ctx->avail_in = in_len;
 950         ctx->avail_out = ZSTR_LEN(out);
 951 
 952         do {
 953                 status = inflate(ctx, flush_type);
 954                 buffer_used = ZSTR_LEN(out) - ctx->avail_out;
 955 
 956                 switch (status) {
 957                         case Z_OK:
 958                                 if (ctx->avail_out == 0) {
 959                                         /* more output buffer space needed; realloc and try again */
 960                                         out = zend_string_realloc(out, ZSTR_LEN(out) + CHUNK_SIZE, 0);
 961                                         ctx->avail_out = CHUNK_SIZE;
 962                                         ctx->next_out = (Bytef *) ZSTR_VAL(out) + buffer_used;
 963                                         break;
 964                                 } else {
 965                                         goto complete;
 966                                 }
 967                         case Z_STREAM_END:
 968                                 inflateReset(ctx);
 969                                 goto complete;
 970                         case Z_BUF_ERROR:
 971                                 if (flush_type == Z_FINISH && ctx->avail_out == 0) {
 972                                         /* more output buffer space needed; realloc and try again */
 973                                         out = zend_string_realloc(out, ZSTR_LEN(out) + CHUNK_SIZE, 0);
 974                                         ctx->avail_out = CHUNK_SIZE;
 975                                         ctx->next_out = (Bytef *) ZSTR_VAL(out) + buffer_used;
 976                                         break;
 977                                 } else {
 978                                         /* No more input data; we're finished */
 979                                         goto complete;
 980                                 }
 981                         case Z_NEED_DICT:
 982                                 if (((php_zlib_context *) ctx)->inflateDict) {
 983                                         php_zlib_context *php_ctx = (php_zlib_context *) ctx;
 984                                         switch (inflateSetDictionary(ctx, (Bytef *) php_ctx->inflateDict, php_ctx->inflateDictlen)) {
 985                                                 case Z_OK:
 986                                                         efree(php_ctx->inflateDict);
 987                                                         php_ctx->inflateDict = NULL;
 988                                                         break;
 989                                                 case Z_DATA_ERROR:
 990                                                         php_error_docref(NULL, E_WARNING, "dictionary does not match expected dictionary (incorrect adler32 hash)");
 991                                                         efree(php_ctx->inflateDict);
 992                                                         zend_string_release(out);
 993                                                         php_ctx->inflateDict = NULL;
 994                                                         RETURN_FALSE;
 995                                                 EMPTY_SWITCH_DEFAULT_CASE()
 996                                         }
 997                                         break;
 998                                 } else {
 999                                         php_error_docref(NULL, E_WARNING, "inflating this data requires a preset dictionary, please specify it in the options array of inflate_init()");
1000                                         RETURN_FALSE;
1001                                 }
1002                         default:
1003                                 zend_string_release(out);
1004                                 php_error_docref(NULL, E_WARNING, "%s", zError(status));
1005                                 RETURN_FALSE;
1006                 }
1007         } while (1);
1008 
1009         complete: {
1010                 out = zend_string_realloc(out, buffer_used, 0);
1011                 ZSTR_VAL(out)[buffer_used] = 0;
1012                 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 PHP_FUNCTION(deflate_init)
1020 {
1021         z_stream *ctx;
1022         zend_long encoding, level = -1, memory = 8, window = 15, strategy = Z_DEFAULT_STRATEGY;
1023         char *dict = NULL;
1024         size_t dictlen = 0;
1025         HashTable *options = NULL;
1026         zval *option_buffer;
1027 
1028         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) {
1029                 return;
1030         }
1031 
1032         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("level"))) != NULL) {
1033                 level = zval_get_long(option_buffer);
1034         }
1035         if (level < -1 || level > 9) {
1036                 php_error_docref(NULL, E_WARNING, "compression level (%pd) must be within -1..9", level);
1037                 RETURN_FALSE;
1038         }
1039 
1040         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("memory"))) != NULL) {
1041                 memory = zval_get_long(option_buffer);
1042         }
1043         if (memory < 1 || memory > 9) {
1044                 php_error_docref(NULL, E_WARNING, "compression memory level (%pd) must be within 1..9", memory);
1045                 RETURN_FALSE;
1046         }
1047 
1048         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) {
1049                 window = zval_get_long(option_buffer);
1050         }
1051         if (window < 8 || window > 15) {
1052                 php_error_docref(NULL, E_WARNING, "zlib window size (logarithm) (%pd) must be within 8..15", window);
1053                 RETURN_FALSE;
1054         }
1055 
1056         if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("strategy"))) != NULL) {
1057                 strategy = zval_get_long(option_buffer);
1058         }
1059         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                         break;
1066                 default:
1067                         php_error_docref(NULL, E_WARNING, "strategy must be one of ZLIB_FILTERED, ZLIB_HUFFMAN_ONLY, ZLIB_RLE, ZLIB_FIXED or ZLIB_DEFAULT_STRATEGY");
1068                         RETURN_FALSE;
1069         }
1070 
1071         if (!zlib_create_dictionary_string(options, &dict, &dictlen)) {
1072                 RETURN_FALSE;
1073         }
1074 
1075         switch (encoding) {
1076                 case PHP_ZLIB_ENCODING_RAW:
1077                 case PHP_ZLIB_ENCODING_GZIP:
1078                 case PHP_ZLIB_ENCODING_DEFLATE:
1079                         break;
1080                 default:
1081                         php_error_docref(NULL, E_WARNING,
1082                                 "encoding mode must be ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE");
1083                         RETURN_FALSE;
1084         }
1085 
1086         ctx = ecalloc(1, sizeof(php_zlib_context));
1087         ctx->zalloc = php_zlib_alloc;
1088         ctx->zfree = php_zlib_free;
1089 
1090         if (encoding < 0) {
1091                 encoding += 15 - window;
1092         } else {
1093                 encoding -= 15 - window;
1094         }
1095 
1096         if (Z_OK == deflateInit2(ctx, level, Z_DEFLATED, encoding, memory, strategy)) {
1097                 if (dict) {
1098                         int success = deflateSetDictionary(ctx, (Bytef *) dict, dictlen);
1099                         ZEND_ASSERT(success == Z_OK);
1100                         efree(dict);
1101                 }
1102 
1103                 RETURN_RES(zend_register_resource(ctx, le_deflate));
1104         } else {
1105                 efree(ctx);
1106                 php_error_docref(NULL, E_WARNING, "failed allocating zlib.deflate context");
1107                 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 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         zend_long flush_type = Z_SYNC_FLUSH;
1122         int status;
1123 
1124         if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "rs|l", &res, &in_buf, &in_len, &flush_type)) {
1125                 return;
1126         }
1127 
1128         if (!(ctx = zend_fetch_resource_ex(res, NULL, le_deflate))) {
1129                 php_error_docref(NULL, E_WARNING, "Invalid deflate resource");
1130                 RETURN_FALSE;
1131         }
1132 
1133         switch (flush_type) {
1134                 case Z_BLOCK:
1135 #if ZLIB_VERNUM < 0x1240L
1136                         php_error_docref(NULL, E_WARNING,
1137                                 "zlib >= 1.2.4 required for BLOCK deflate; current version: %s", ZLIB_VERSION);
1138                         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                         break;
1146 
1147                 default:
1148                         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                         RETURN_FALSE;
1151         }
1152 
1153         if (in_len <= 0 && flush_type != Z_FINISH) {
1154                 RETURN_EMPTY_STRING();
1155         }
1156 
1157         out_size = PHP_ZLIB_BUFFER_SIZE_GUESS(ctx->total_in + in_len);
1158         out_size = (ctx->total_out >= out_size) ? 16 : (out_size - ctx->total_out);
1159         out_size = (out_size < 16) ? 16 : out_size;
1160         out = zend_string_alloc(out_size, 0);
1161 
1162         ctx->next_in = (Bytef *) in_buf;
1163         ctx->next_out = (Bytef *) ZSTR_VAL(out);
1164         ctx->avail_in = in_len;
1165         ctx->avail_out = ZSTR_LEN(out);
1166 
1167         status = deflate(ctx, flush_type);
1168         switch (status) {
1169                 case Z_OK:
1170                         ZSTR_LEN(out) = (char *) ctx->next_out - ZSTR_VAL(out);
1171                         ZSTR_VAL(out)[ZSTR_LEN(out)] = 0;
1172                         RETURN_STR(out);
1173                         break;
1174                 case Z_STREAM_END:
1175                         ZSTR_LEN(out) = (char *) ctx->next_out - ZSTR_VAL(out);
1176                         ZSTR_VAL(out)[ZSTR_LEN(out)] = 0;
1177                         deflateReset(ctx);
1178                         RETURN_STR(out);
1179                         break;
1180                 default:
1181                         zend_string_release(out);
1182                         php_error_docref(NULL, E_WARNING, "zlib error (%s)", zError(status));
1183                         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 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         char *base = (char *) mh_arg2;
1361 #else
1362         char *base;
1363 
1364         base = (char *) ts_resource(*((int *) mh_arg2));
1365 #endif
1366 
1367         if (new_value == NULL) {
1368                 return FAILURE;
1369         }
1370 
1371         if (!strncasecmp(ZSTR_VAL(new_value), "off", sizeof("off"))) {
1372                 int_value = 0;
1373         } else if (!strncasecmp(ZSTR_VAL(new_value), "on", sizeof("on"))) {
1374                 int_value = 1;
1375         } else {
1376                 int_value = zend_atoi(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
1377         }
1378         ini_value = zend_ini_string("output_handler", sizeof("output_handler"), 0);
1379 
1380         if (ini_value && *ini_value && int_value) {
1381                 php_error_docref("ref.outcontrol", E_CORE_ERROR, "Cannot use both zlib.output_compression and output_handler together!!");
1382                 return FAILURE;
1383         }
1384         if (stage == PHP_INI_STAGE_RUNTIME) {
1385                 int status = php_output_get_status();
1386                 if (status & PHP_OUTPUT_SENT) {
1387                         php_error_docref("ref.outcontrol", E_WARNING, "Cannot change zlib.output_compression - headers already sent");
1388                         return FAILURE;
1389                 }
1390         }
1391 
1392         p = (zend_long *) (base+(size_t) mh_arg1);
1393         *p = int_value;
1394 
1395         ZLIBG(output_compression) = ZLIBG(output_compression_default);
1396         if (stage == PHP_INI_STAGE_RUNTIME && int_value) {
1397                 if (!php_output_handler_started(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME))) {
1398                         php_zlib_output_compression_start();
1399                 }
1400         }
1401 
1402         return SUCCESS;
1403 }
1404 /* }}} */
1405 
1406 /* {{{ OnUpdate_zlib_output_handler */
1407 static PHP_INI_MH(OnUpdate_zlib_output_handler)
1408 {
1409         if (stage == PHP_INI_STAGE_RUNTIME && (php_output_get_status() & PHP_OUTPUT_SENT)) {
1410                 php_error_docref("ref.outcontrol", E_WARNING, "Cannot change zlib.output_handler - headers already sent");
1411                 return FAILURE;
1412         }
1413 
1414         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 static PHP_MINIT_FUNCTION(zlib)
1429 {
1430         php_register_url_stream_wrapper("compress.zlib", &php_stream_gzip_wrapper);
1431         php_stream_filter_register_factory("zlib.*", &php_zlib_filter_factory);
1432 
1433         php_output_handler_alias_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_handler_init);
1434         php_output_handler_conflict_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_conflict_check);
1435         php_output_handler_conflict_register(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), php_zlib_output_conflict_check);
1436 
1437         le_deflate = zend_register_list_destructors_ex(deflate_rsrc_dtor, NULL, "zlib.deflate", module_number);
1438         le_inflate = zend_register_list_destructors_ex(inflate_rsrc_dtor, NULL, "zlib.inflate", module_number);
1439 
1440         REGISTER_LONG_CONSTANT("FORCE_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
1441         REGISTER_LONG_CONSTANT("FORCE_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
1442 
1443         REGISTER_LONG_CONSTANT("ZLIB_ENCODING_RAW", PHP_ZLIB_ENCODING_RAW, CONST_CS|CONST_PERSISTENT);
1444         REGISTER_LONG_CONSTANT("ZLIB_ENCODING_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
1445         REGISTER_LONG_CONSTANT("ZLIB_ENCODING_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
1446 
1447         REGISTER_LONG_CONSTANT("ZLIB_NO_FLUSH", Z_NO_FLUSH, CONST_CS|CONST_PERSISTENT);
1448         REGISTER_LONG_CONSTANT("ZLIB_PARTIAL_FLUSH", Z_PARTIAL_FLUSH, CONST_CS|CONST_PERSISTENT);
1449         REGISTER_LONG_CONSTANT("ZLIB_SYNC_FLUSH", Z_SYNC_FLUSH, CONST_CS|CONST_PERSISTENT);
1450         REGISTER_LONG_CONSTANT("ZLIB_FULL_FLUSH", Z_FULL_FLUSH, CONST_CS|CONST_PERSISTENT);
1451         REGISTER_LONG_CONSTANT("ZLIB_BLOCK", Z_BLOCK, CONST_CS|CONST_PERSISTENT);
1452         REGISTER_LONG_CONSTANT("ZLIB_FINISH", Z_FINISH, CONST_CS|CONST_PERSISTENT);
1453 
1454         REGISTER_LONG_CONSTANT("ZLIB_FILTERED", Z_FILTERED, CONST_CS|CONST_PERSISTENT);
1455         REGISTER_LONG_CONSTANT("ZLIB_HUFFMAN_ONLY", Z_HUFFMAN_ONLY, CONST_CS|CONST_PERSISTENT);
1456         REGISTER_LONG_CONSTANT("ZLIB_RLE", Z_RLE, CONST_CS|CONST_PERSISTENT);
1457         REGISTER_LONG_CONSTANT("ZLIB_FIXED", Z_FIXED, CONST_CS|CONST_PERSISTENT);
1458         REGISTER_LONG_CONSTANT("ZLIB_DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY, CONST_CS|CONST_PERSISTENT);
1459 
1460         REGISTER_STRING_CONSTANT("ZLIB_VERSION", ZLIB_VERSION, CONST_CS|CONST_PERSISTENT);
1461         REGISTER_LONG_CONSTANT("ZLIB_VERNUM", ZLIB_VERNUM, CONST_CS|CONST_PERSISTENT);
1462 
1463         REGISTER_INI_ENTRIES();
1464         return SUCCESS;
1465 }
1466 /* }}} */
1467 
1468 /* {{{ PHP_MSHUTDOWN_FUNCTION */
1469 static PHP_MSHUTDOWN_FUNCTION(zlib)
1470 {
1471         php_unregister_url_stream_wrapper("zlib");
1472         php_stream_filter_unregister_factory("zlib.*");
1473 
1474         UNREGISTER_INI_ENTRIES();
1475 
1476         return SUCCESS;
1477 }
1478 /* }}} */
1479 
1480 /* {{{ PHP_RINIT_FUNCTION */
1481 static PHP_RINIT_FUNCTION(zlib)
1482 {
1483         ZLIBG(compression_coding) = 0;
1484     if (!ZLIBG(handler_registered)) {
1485         ZLIBG(output_compression) = ZLIBG(output_compression_default);
1486         php_zlib_output_compression_start();
1487     }
1488 
1489         return SUCCESS;
1490 }
1491 /* }}} */
1492 
1493 /* {{{ PHP_RSHUTDOWN_FUNCTION */
1494 static PHP_RSHUTDOWN_FUNCTION(zlib)
1495 {
1496         php_zlib_cleanup_ob_gzhandler_mess();
1497     ZLIBG(handler_registered) = 0;
1498 
1499     return SUCCESS;
1500 }
1501 /* }}} */
1502 
1503 /* {{{ PHP_MINFO_FUNCTION */
1504 static PHP_MINFO_FUNCTION(zlib)
1505 {
1506         php_info_print_table_start();
1507         php_info_print_table_header(2, "ZLib Support", "enabled");
1508         php_info_print_table_row(2, "Stream Wrapper", "compress.zlib://");
1509         php_info_print_table_row(2, "Stream Filter", "zlib.inflate, zlib.deflate");
1510         php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION);
1511         php_info_print_table_row(2, "Linked Version", (char *) zlibVersion());
1512         php_info_print_table_end();
1513 
1514         DISPLAY_INI_ENTRIES();
1515 }
1516 /* }}} */
1517 
1518 /* {{{ ZEND_MODULE_GLOBALS_CTOR */
1519 static PHP_GINIT_FUNCTION(zlib)
1520 {
1521 #if defined(COMPILE_DL_ZLIB) && defined(ZTS)
1522         ZEND_TSRMLS_CACHE_UPDATE();
1523 #endif
1524         zlib_globals->ob_gzhandler = NULL;
1525     zlib_globals->handler_registered = 0;
1526 }
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  */

/* [<][>][^][v][top][bottom][index][help] */