Annotation of embedaddon/php/ext/zlib/zlib.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:    | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       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>                       |
1.1.1.2   misho      16:    |          Stefan Röhrich <sr@linux.de>                                |
1.1       misho      17:    |          Zeev Suraski <zeev@zend.com>                                |
                     18:    |          Jade Nicoletti <nicoletti@nns.ch>                           |
1.1.1.2   misho      19:    |          Michael Wallner <mike@php.net>                              |
1.1       misho      20:    +----------------------------------------------------------------------+
                     21:  */
                     22: 
1.1.1.2   misho      23: /* $Id$ */
1.1       misho      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"
1.1.1.2   misho      33: #include "ext/standard/file.h"
                     34: #include "ext/standard/php_string.h"
1.1       misho      35: #include "php_zlib.h"
                     36: 
1.1.1.2   misho      37: ZEND_DECLARE_MODULE_GLOBALS(zlib);
1.1       misho      38: 
                     39: /* {{{ Memory management wrappers */
                     40: 
                     41: static voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size)
                     42: {
                     43:        return (voidpf)safe_emalloc(items, size, 0);
                     44: }
                     45: 
                     46: static void php_zlib_free(voidpf opaque, voidpf address)
                     47: {
                     48:        efree((void*)address);
                     49: }
                     50: /* }}} */
                     51: 
1.1.1.2   misho      52: /* {{{ php_zlib_output_conflict_check() */
                     53: static int php_zlib_output_conflict_check(const char *handler_name, size_t handler_name_len TSRMLS_DC)
1.1       misho      54: {
1.1.1.2   misho      55:        if (php_output_get_level(TSRMLS_C) > 0) {
                     56:                if (php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME) TSRMLS_CC)
                     57:                ||      php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("ob_gzhandler") TSRMLS_CC)
                     58:                ||  php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("mb_output_handler") TSRMLS_CC)
                     59:                ||      php_output_handler_conflict(handler_name, handler_name_len, ZEND_STRL("URL-Rewriter") TSRMLS_CC)) {
                     60:                        return FAILURE;
                     61:                }
1.1       misho      62:        }
1.1.1.2   misho      63:        return SUCCESS;
                     64: }
                     65: /* }}} */
1.1       misho      66: 
1.1.1.2   misho      67: /* {{{ php_zlib_output_encoding() */
                     68: static int php_zlib_output_encoding(TSRMLS_D)
                     69: {
                     70:        zval **enc;
1.1       misho      71: 
1.1.1.2   misho      72:        if (!ZLIBG(compression_coding)) {
                     73:                zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC);
                     74:                if (PG(http_globals)[TRACK_VARS_SERVER] && SUCCESS == zend_hash_find(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_ACCEPT_ENCODING", sizeof("HTTP_ACCEPT_ENCODING"), (void *) &enc)) {
                     75:                        convert_to_string(*enc);
                     76:                        if (strstr(Z_STRVAL_PP(enc), "gzip")) {
                     77:                                ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_GZIP;
                     78:                        } else if (strstr(Z_STRVAL_PP(enc), "deflate")) {
                     79:                                ZLIBG(compression_coding) = PHP_ZLIB_ENCODING_DEFLATE;
                     80:                        }
                     81:                }
1.1       misho      82:        }
1.1.1.2   misho      83:        return ZLIBG(compression_coding);
                     84: }
                     85: /* }}} */
1.1       misho      86: 
1.1.1.2   misho      87: /* {{{ php_zlib_output_handler_ex() */
                     88: static int php_zlib_output_handler_ex(php_zlib_context *ctx, php_output_context *output_context)
                     89: {
                     90:        int flags = Z_SYNC_FLUSH;
                     91:        PHP_OUTPUT_TSRMLS(output_context);
                     92: 
                     93:        if (output_context->op & PHP_OUTPUT_HANDLER_START) {
                     94:                /* start up */
                     95:                if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) {
                     96:                        return FAILURE;
                     97:                }
1.1       misho      98:        }
                     99: 
1.1.1.2   misho     100:        if (output_context->op & PHP_OUTPUT_HANDLER_CLEAN) {
                    101:                /* free buffers */
                    102:                deflateEnd(&ctx->Z);
                    103: 
                    104:                if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
                    105:                        /* discard */
                    106:                        return SUCCESS;
                    107:                } else {
                    108:                        /* restart */
                    109:                        if (Z_OK != deflateInit2(&ctx->Z, ZLIBG(output_compression_level), Z_DEFLATED, ZLIBG(compression_coding), MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) {
                    110:                                return FAILURE;
                    111:                        }
                    112:                        ctx->buffer.used = 0;
                    113:                }
                    114:        } else {
                    115:                if (output_context->in.used) {
                    116:                        /* append input */
                    117:                        if (ctx->buffer.free < output_context->in.used) {
                    118:                                if (!(ctx->buffer.aptr = erealloc_recoverable(ctx->buffer.data, ctx->buffer.used + ctx->buffer.free + output_context->in.used))) {
                    119:                                        deflateEnd(&ctx->Z);
                    120:                                        return FAILURE;
                    121:                                }
                    122:                                ctx->buffer.data = ctx->buffer.aptr;
                    123:                                ctx->buffer.free += output_context->in.used;
                    124:                        }
                    125:                        memcpy(ctx->buffer.data + ctx->buffer.used, output_context->in.data, output_context->in.used);
                    126:                        ctx->buffer.free -= output_context->in.used;
                    127:                        ctx->buffer.used += output_context->in.used;
                    128:                }
                    129:                output_context->out.size = PHP_ZLIB_BUFFER_SIZE_GUESS(output_context->in.used);
                    130:                output_context->out.data = emalloc(output_context->out.size);
                    131:                output_context->out.free = 1;
                    132:                output_context->out.used = 0;
                    133: 
                    134:                ctx->Z.avail_in = ctx->buffer.used;
                    135:                ctx->Z.next_in = (Bytef *) ctx->buffer.data;
                    136:                ctx->Z.avail_out = output_context->out.size;
                    137:                ctx->Z.next_out = (Bytef *) output_context->out.data;
                    138: 
                    139:                if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
                    140:                        flags = Z_FINISH;
                    141:                } else if (output_context->op & PHP_OUTPUT_HANDLER_FLUSH) {
                    142:                        flags = Z_FULL_FLUSH;
                    143:                }
                    144: 
                    145:                switch (deflate(&ctx->Z, flags)) {
                    146:                        case Z_OK:
                    147:                                if (flags == Z_FINISH) {
                    148:                                        deflateEnd(&ctx->Z);
                    149:                                        return FAILURE;
                    150:                                }
                    151:                        case Z_STREAM_END:
                    152:                                if (ctx->Z.avail_in) {
                    153:                                        memmove(ctx->buffer.data, ctx->buffer.data + ctx->buffer.used - ctx->Z.avail_in, ctx->Z.avail_in);
                    154:                                }
                    155:                                ctx->buffer.free += ctx->buffer.used - ctx->Z.avail_in;
                    156:                                ctx->buffer.used = ctx->Z.avail_in;
                    157:                                output_context->out.used = output_context->out.size - ctx->Z.avail_out;
                    158:                                break;
                    159:                        default:
                    160:                                deflateEnd(&ctx->Z);
                    161:                                return FAILURE;
                    162:                }
1.1       misho     163: 
1.1.1.2   misho     164:                if (output_context->op & PHP_OUTPUT_HANDLER_FINAL) {
                    165:                        deflateEnd(&ctx->Z);
                    166:                }
1.1       misho     167:        }
                    168: 
1.1.1.2   misho     169:        return SUCCESS;
1.1       misho     170: }
                    171: /* }}} */
                    172: 
1.1.1.2   misho     173: /* {{{ php_zlib_output_handler() */
                    174: static int php_zlib_output_handler(void **handler_context, php_output_context *output_context)
1.1       misho     175: {
1.1.1.2   misho     176:        php_zlib_context *ctx = *(php_zlib_context **) handler_context;
                    177:        PHP_OUTPUT_TSRMLS(output_context);
1.1       misho     178: 
1.1.1.2   misho     179:        if (!php_zlib_output_encoding(TSRMLS_C)) {
                    180:                /* "Vary: Accept-Encoding" header sent along uncompressed content breaks caching in MSIE,
                    181:                        so let's just send it with successfully compressed content or unless the complete
                    182:                        buffer gets discarded, see http://bugs.php.net/40325;
                    183: 
                    184:                        Test as follows:
                    185:                        +Vary: $ HTTP_ACCEPT_ENCODING=gzip ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n";'
                    186:                        +Vary: $ HTTP_ACCEPT_ENCODING= ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n";'
                    187:                        -Vary: $ HTTP_ACCEPT_ENCODING=gzip ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n"; ob_end_clean();'
                    188:                        -Vary: $ HTTP_ACCEPT_ENCODING= ./sapi/cgi/php <<<'<?php ob_start("ob_gzhandler"); echo "foo\n"; ob_end_clean();'
                    189:                */
1.1.1.3 ! misho     190:                if ((output_context->op & PHP_OUTPUT_HANDLER_START)
        !           191:                &&      (output_context->op != (PHP_OUTPUT_HANDLER_START|PHP_OUTPUT_HANDLER_CLEAN|PHP_OUTPUT_HANDLER_FINAL))
        !           192:                ) {
1.1.1.2   misho     193:                        sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
                    194:                }
                    195:                return FAILURE;
                    196:        }
1.1       misho     197: 
1.1.1.2   misho     198:        if (SUCCESS != php_zlib_output_handler_ex(ctx, output_context)) {
1.1       misho     199:                return FAILURE;
                    200:        }
                    201: 
1.1.1.2   misho     202:        if (!(output_context->op & PHP_OUTPUT_HANDLER_CLEAN)) {
                    203:                int flags;
                    204: 
                    205:                if (SUCCESS == php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_GET_FLAGS, &flags TSRMLS_CC)) {
                    206:                        /* only run this once */
                    207:                        if (!(flags & PHP_OUTPUT_HANDLER_STARTED)) {
                    208:                                if (SG(headers_sent) || !ZLIBG(output_compression)) {
                    209:                                        deflateEnd(&ctx->Z);
                    210:                                        return FAILURE;
                    211:                                }
                    212:                                switch (ZLIBG(compression_coding)) {
                    213:                                        case PHP_ZLIB_ENCODING_GZIP:
                    214:                                                sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1 TSRMLS_CC);
                    215:                                                break;
                    216:                                        case PHP_ZLIB_ENCODING_DEFLATE:
                    217:                                                sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1 TSRMLS_CC);
                    218:                                                break;
                    219:                                        default:
                    220:                                                deflateEnd(&ctx->Z);
                    221:                                                return FAILURE;
                    222:                                }
                    223:                                sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
                    224:                                php_output_handler_hook(PHP_OUTPUT_HANDLER_HOOK_IMMUTABLE, NULL TSRMLS_CC);
                    225:                        }
                    226:                }
                    227:        }
1.1       misho     228: 
                    229:        return SUCCESS;
                    230: }
                    231: /* }}} */
                    232: 
1.1.1.2   misho     233: /* {{{ php_zlib_output_handler_context_init() */
                    234: static php_zlib_context *php_zlib_output_handler_context_init(TSRMLS_D)
1.1       misho     235: {
1.1.1.2   misho     236:        php_zlib_context *ctx = (php_zlib_context *) ecalloc(1, sizeof(php_zlib_context));
                    237:        ctx->Z.zalloc = php_zlib_alloc;
                    238:        ctx->Z.zfree = php_zlib_free;
                    239:        return ctx;
1.1       misho     240: }
                    241: /* }}} */
                    242: 
1.1.1.2   misho     243: /* {{{ php_zlib_output_handler_context_dtor() */
                    244: static void php_zlib_output_handler_context_dtor(void *opaq TSRMLS_DC)
1.1       misho     245: {
1.1.1.2   misho     246:        php_zlib_context *ctx = (php_zlib_context *) opaq;
1.1       misho     247: 
1.1.1.2   misho     248:        if (ctx) {
                    249:                if (ctx->buffer.data) {
                    250:                        efree(ctx->buffer.data);
                    251:                }
                    252:                efree(ctx);
                    253:        }
1.1       misho     254: }
                    255: /* }}} */
                    256: 
1.1.1.2   misho     257: /* {{{ php_zlib_output_handler_init() */
                    258: static php_output_handler *php_zlib_output_handler_init(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC)
1.1       misho     259: {
1.1.1.2   misho     260:        php_output_handler *h = NULL;
1.1       misho     261: 
1.1.1.2   misho     262:        if (!ZLIBG(output_compression)) {
                    263:                ZLIBG(output_compression) = chunk_size ? chunk_size : PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
                    264:        }
1.1       misho     265: 
1.1.1.3 ! misho     266:     ZLIBG(handler_registered) = 1;
        !           267: 
1.1.1.2   misho     268:        if ((h = php_output_handler_create_internal(handler_name, handler_name_len, php_zlib_output_handler, chunk_size, flags TSRMLS_CC))) {
                    269:                php_output_handler_set_context(h, php_zlib_output_handler_context_init(TSRMLS_C), php_zlib_output_handler_context_dtor TSRMLS_CC);
                    270:        }
                    271: 
                    272:        return h;
1.1       misho     273: }
                    274: /* }}} */
                    275: 
1.1.1.2   misho     276: /* {{{ php_zlib_output_compression_start() */
                    277: static void php_zlib_output_compression_start(TSRMLS_D)
1.1       misho     278: {
1.1.1.2   misho     279:        zval *zoh;
                    280:        php_output_handler *h;
1.1       misho     281: 
1.1.1.2   misho     282:        switch (ZLIBG(output_compression)) {
                    283:                case 0:
                    284:                        break;
                    285:                case 1:
                    286:                        ZLIBG(output_compression) = PHP_OUTPUT_HANDLER_DEFAULT_SIZE;
                    287:                        /* break omitted intentionally */
                    288:                default:
1.1.1.3 ! misho     289:                        if (    php_zlib_output_encoding(TSRMLS_C) &&
        !           290:                                        (h = php_zlib_output_handler_init(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC)) &&
1.1.1.2   misho     291:                                        (SUCCESS == php_output_handler_start(h TSRMLS_CC))) {
                    292:                                if (ZLIBG(output_handler) && *ZLIBG(output_handler)) {
                    293:                                        MAKE_STD_ZVAL(zoh);
                    294:                                        ZVAL_STRING(zoh, ZLIBG(output_handler), 1);
                    295:                                        php_output_start_user(zoh, ZLIBG(output_compression), PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC);
                    296:                                        zval_ptr_dtor(&zoh);
                    297:                                }
                    298:                        }
                    299:                        break;
                    300:        }
1.1       misho     301: }
                    302: /* }}} */
                    303: 
1.1.1.2   misho     304: /* {{{ php_zlib_encode() */
                    305: static int php_zlib_encode(const char *in_buf, size_t in_len, char **out_buf, size_t *out_len, int encoding, int level TSRMLS_DC)
1.1       misho     306: {
1.1.1.2   misho     307:        int status;
                    308:        z_stream Z;
1.1       misho     309: 
1.1.1.2   misho     310:        memset(&Z, 0, sizeof(z_stream));
                    311:        Z.zalloc = php_zlib_alloc;
                    312:        Z.zfree = php_zlib_free;
                    313: 
                    314:        if (Z_OK == (status = deflateInit2(&Z, level, Z_DEFLATED, encoding, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY))) {
                    315:                *out_len = PHP_ZLIB_BUFFER_SIZE_GUESS(in_len);
                    316:                *out_buf = emalloc(*out_len);
                    317: 
                    318:                Z.next_in = (Bytef *) in_buf;
                    319:                Z.next_out = (Bytef *) *out_buf;
                    320:                Z.avail_in = in_len;
                    321:                Z.avail_out = *out_len;
                    322: 
                    323:                status = deflate(&Z, Z_FINISH);
                    324:                deflateEnd(&Z);
                    325: 
                    326:                if (Z_STREAM_END == status) {
                    327:                        /* size buffer down to actual length */
                    328:                        *out_buf = erealloc(*out_buf, Z.total_out + 1);
                    329:                        (*out_buf)[*out_len = Z.total_out] = '\0';
                    330:                        return SUCCESS;
                    331:                } else {
                    332:                        efree(*out_buf);
                    333:                }
1.1       misho     334:        }
                    335: 
1.1.1.2   misho     336:        *out_buf = NULL;
                    337:        *out_len = 0;
1.1       misho     338: 
1.1.1.2   misho     339:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", zError(status));
                    340:        return FAILURE;
                    341: }
                    342: /* }}} */
1.1       misho     343: 
1.1.1.2   misho     344: /* {{{ php_zlib_inflate_rounds() */
                    345: static inline int php_zlib_inflate_rounds(z_stream *Z, size_t max, char **buf, size_t *len)
                    346: {
                    347:        int status, round = 0;
                    348:        php_zlib_buffer buffer = {NULL, NULL, 0, 0, 0};
1.1       misho     349: 
1.1.1.2   misho     350:        *buf = NULL;
                    351:        *len = 0;
1.1       misho     352: 
1.1.1.2   misho     353:        buffer.size = (max && (max < Z->avail_in)) ? max : Z->avail_in;
1.1       misho     354: 
1.1.1.2   misho     355:        do {
                    356:                if ((max && (max <= buffer.used)) || !(buffer.aptr = erealloc_recoverable(buffer.data, buffer.size))) {
                    357:                        status = Z_MEM_ERROR;
1.1       misho     358:                } else {
1.1.1.2   misho     359:                        buffer.data = buffer.aptr;
                    360:                        Z->avail_out = buffer.free = buffer.size - buffer.used;
                    361:                        Z->next_out = (Bytef *) buffer.data + buffer.used;
                    362: #if 0
                    363:                        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);
                    364: #endif
                    365:                        status = inflate(Z, Z_NO_FLUSH);
                    366: 
                    367:                        buffer.used += buffer.free - Z->avail_out;
                    368:                        buffer.free = Z->avail_out;
                    369: #if 0
                    370:                        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);
                    371: #endif
                    372:                        buffer.size += (buffer.size >> 3) + 1;
1.1       misho     373:                }
1.1.1.2   misho     374:        } while ((Z_BUF_ERROR == status || (Z_OK == status && Z->avail_in)) && ++round < 100);
                    375: 
                    376:        if (status == Z_STREAM_END) {
                    377:                buffer.data = erealloc(buffer.data, buffer.used + 1);
                    378:                buffer.data[buffer.used] = '\0';
                    379:                *buf = buffer.data;
                    380:                *len = buffer.used;
                    381:        } else {
                    382:                if (buffer.data) {
                    383:                        efree(buffer.data);
                    384:                }
                    385:                /* HACK: See zlib/examples/zpipe.c inf() function for explanation. */
                    386:                /* This works as long as this function is not used for streaming. Required to catch very short invalid data. */
                    387:                status = (status == Z_OK) ? Z_DATA_ERROR : status;
1.1       misho     388:        }
1.1.1.2   misho     389:        return status;
1.1       misho     390: }
                    391: /* }}} */
                    392: 
1.1.1.2   misho     393: /* {{{ php_zlib_decode() */
                    394: 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 TSRMLS_DC)
1.1       misho     395: {
1.1.1.2   misho     396:        int status = Z_DATA_ERROR;
                    397:        z_stream Z;
1.1       misho     398: 
1.1.1.2   misho     399:        memset(&Z, 0, sizeof(z_stream));
                    400:        Z.zalloc = php_zlib_alloc;
                    401:        Z.zfree = php_zlib_free;
                    402: 
                    403:        if (in_len) {
                    404: retry_raw_inflate:
                    405:                status = inflateInit2(&Z, encoding);
                    406:                if (Z_OK == status) {
                    407:                        Z.next_in = (Bytef *) in_buf;
                    408:                        Z.avail_in = in_len + 1; /* NOTE: data must be zero terminated */
                    409: 
                    410:                        switch (status = php_zlib_inflate_rounds(&Z, max_len, out_buf, out_len)) {
                    411:                                case Z_STREAM_END:
                    412:                                        inflateEnd(&Z);
                    413:                                        return SUCCESS;
                    414: 
                    415:                                case Z_DATA_ERROR:
                    416:                                        /* raw deflated data? */
                    417:                                        if (PHP_ZLIB_ENCODING_ANY == encoding) {
                    418:                                                inflateEnd(&Z);
                    419:                                                encoding = PHP_ZLIB_ENCODING_RAW;
                    420:                                                goto retry_raw_inflate;
                    421:                                        }
                    422:                        }
                    423:                        inflateEnd(&Z);
                    424:                }
1.1       misho     425:        }
                    426: 
1.1.1.2   misho     427:        *out_buf = NULL;
                    428:        *out_len = 0;
1.1       misho     429: 
1.1.1.2   misho     430:        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", zError(status));
                    431:        return FAILURE;
                    432: }
                    433: /* }}} */
1.1       misho     434: 
1.1.1.2   misho     435: /* {{{ php_zlib_cleanup_ob_gzhandler_mess() */
                    436: static void php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_D)
                    437: {
                    438:        if (ZLIBG(ob_gzhandler)) {
                    439:                deflateEnd(&(ZLIBG(ob_gzhandler)->Z));
                    440:                php_zlib_output_handler_context_dtor(ZLIBG(ob_gzhandler) TSRMLS_CC);
                    441:                ZLIBG(ob_gzhandler) = NULL;
1.1       misho     442:        }
                    443: }
                    444: /* }}} */
                    445: 
1.1.1.2   misho     446: /* {{{ proto string ob_gzhandler(string data, int flags)
                    447:    Legacy hack */
                    448: static PHP_FUNCTION(ob_gzhandler)
1.1       misho     449: {
1.1.1.2   misho     450:        char *in_str;
                    451:        int in_len;
1.1       misho     452:        long flags = 0;
1.1.1.2   misho     453:        php_output_context ctx = {0};
                    454:        int encoding, rv;
1.1       misho     455: 
1.1.1.2   misho     456:        /*
                    457:         * NOTE that the real ob_gzhandler is an alias to "zlib output compression".
                    458:         * This is a really bad hack, because
                    459:         * - we have to initialize a php_zlib_context on demand
                    460:         * - we have to clean it up in RSHUTDOWN
                    461:         * - OG(running) is not set or set to any other output handler
                    462:         * - we have to mess around with php_output_context */
1.1       misho     463: 
1.1.1.2   misho     464:        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &in_str, &in_len, &flags)) {
1.1       misho     465:                RETURN_FALSE;
                    466:        }
                    467: 
1.1.1.2   misho     468:        if (!(encoding = php_zlib_output_encoding(TSRMLS_C))) {
                    469:                RETURN_FALSE;
1.1       misho     470:        }
                    471: 
1.1.1.2   misho     472:        if (flags & PHP_OUTPUT_HANDLER_START) {
                    473:                switch (encoding) {
                    474:                        case PHP_ZLIB_ENCODING_GZIP:
                    475:                                sapi_add_header_ex(ZEND_STRL("Content-Encoding: gzip"), 1, 1 TSRMLS_CC);
                    476:                                break;
                    477:                        case PHP_ZLIB_ENCODING_DEFLATE:
                    478:                                sapi_add_header_ex(ZEND_STRL("Content-Encoding: deflate"), 1, 1 TSRMLS_CC);
                    479:                                break;
                    480:                }
                    481:                sapi_add_header_ex(ZEND_STRL("Vary: Accept-Encoding"), 1, 1 TSRMLS_CC);
1.1       misho     482:        }
                    483: 
1.1.1.2   misho     484:        if (!ZLIBG(ob_gzhandler)) {
                    485:                ZLIBG(ob_gzhandler) = php_zlib_output_handler_context_init(TSRMLS_C);
1.1       misho     486:        }
                    487: 
1.1.1.2   misho     488:        TSRMLS_SET_CTX(ctx.tsrm_ls);
                    489:        ctx.op = flags;
                    490:        ctx.in.data = in_str;
                    491:        ctx.in.used = in_len;
                    492: 
                    493:        rv = php_zlib_output_handler_ex(ZLIBG(ob_gzhandler), &ctx);
                    494: 
                    495:        if (SUCCESS != rv) {
                    496:                if (ctx.out.data && ctx.out.free) {
                    497:                        efree(ctx.out.data);
                    498:                }
                    499:                php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_C);
                    500:                RETURN_FALSE;
1.1       misho     501:        }
                    502: 
1.1.1.2   misho     503:        if (ctx.out.data) {
                    504:                RETVAL_STRINGL(ctx.out.data, ctx.out.used, 1);
                    505:                if (ctx.out.free) {
                    506:                        efree(ctx.out.data);
                    507:                }
1.1       misho     508:        } else {
1.1.1.2   misho     509:                RETVAL_EMPTY_STRING();
1.1       misho     510:        }
                    511: }
                    512: /* }}} */
                    513: 
1.1.1.2   misho     514: /* {{{ proto string zlib_get_coding_type(void)
                    515:    Returns the coding type used for output compression */
                    516: static PHP_FUNCTION(zlib_get_coding_type)
                    517: {
                    518:        if (zend_parse_parameters_none() == FAILURE) {
1.1       misho     519:                return;
                    520:        }
1.1.1.2   misho     521:        switch (ZLIBG(compression_coding)) {
                    522:                case PHP_ZLIB_ENCODING_GZIP:
                    523:                        RETURN_STRINGL("gzip", sizeof("gzip") - 1, 1);
                    524:                case PHP_ZLIB_ENCODING_DEFLATE:
                    525:                        RETURN_STRINGL("deflate", sizeof("deflate") - 1, 1);
                    526:                default:
                    527:                        RETURN_FALSE;
1.1       misho     528:        }
                    529: }
                    530: /* }}} */
                    531: 
1.1.1.2   misho     532: /* {{{ proto array gzfile(string filename [, int use_include_path])
                    533:    Read and uncompress entire .gz-file into an array */
                    534: static PHP_FUNCTION(gzfile)
                    535: {
                    536:        char *filename;
                    537:        int filename_len;
                    538:        int flags = REPORT_ERRORS;
                    539:        char buf[8192] = {0};
                    540:        register int i = 0;
                    541:        long use_include_path = 0;
                    542:        php_stream *stream;
1.1       misho     543: 
1.1.1.2   misho     544:        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &use_include_path)) {
1.1       misho     545:                return;
                    546:        }
                    547: 
1.1.1.2   misho     548:        if (use_include_path) {
                    549:                flags |= USE_PATH;
1.1       misho     550:        }
                    551: 
1.1.1.2   misho     552:        /* using a stream here is a bit more efficient (resource wise) than php_gzopen_wrapper */
                    553:        stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC TSRMLS_CC);
1.1       misho     554: 
1.1.1.2   misho     555:        if (!stream) {
                    556:                /* Error reporting is already done by stream code */
1.1       misho     557:                RETURN_FALSE;
                    558:        }
                    559: 
1.1.1.2   misho     560:        /* Initialize return array */
                    561:        array_init(return_value);
1.1       misho     562: 
1.1.1.2   misho     563:        /* Now loop through the file and do the magic quotes thing if needed */
                    564:        memset(buf, 0, sizeof(buf));
                    565:            
                    566:        while (php_stream_gets(stream, buf, sizeof(buf) - 1) != NULL) {
                    567:                add_index_string(return_value, i++, buf, 1);
1.1       misho     568:        }
1.1.1.2   misho     569:        php_stream_close(stream);
1.1       misho     570: }
                    571: /* }}} */
                    572: 
1.1.1.2   misho     573: /* {{{ proto resource gzopen(string filename, string mode [, int use_include_path])
                    574:    Open a .gz-file and return a .gz-file pointer */
                    575: static PHP_FUNCTION(gzopen)
                    576: {
                    577:        char *filename;
                    578:        char *mode;
                    579:        int filename_len, mode_len;
                    580:        int flags = REPORT_ERRORS;
                    581:        php_stream *stream;
                    582:        long use_include_path = 0;
1.1       misho     583: 
1.1.1.2   misho     584:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &filename, &filename_len, &mode, &mode_len, &use_include_path) == FAILURE) {
1.1       misho     585:                return;
                    586:        }
                    587: 
1.1.1.2   misho     588:        if (use_include_path) {
                    589:                flags |= USE_PATH;
1.1       misho     590:        }
                    591: 
1.1.1.2   misho     592:        stream = php_stream_gzopen(NULL, filename, mode, flags, NULL, NULL STREAMS_CC TSRMLS_CC);
1.1       misho     593: 
1.1.1.2   misho     594:        if (!stream) {
1.1       misho     595:                RETURN_FALSE;
                    596:        }
1.1.1.2   misho     597:        php_stream_to_zval(stream, return_value);
                    598: }
                    599: /* }}} */
1.1       misho     600: 
1.1.1.2   misho     601: /* {{{ proto int readgzfile(string filename [, int use_include_path])
                    602:    Output a .gz-file */
                    603: static PHP_FUNCTION(readgzfile)
                    604: {
                    605:        char *filename;
                    606:        int filename_len;
                    607:        int flags = REPORT_ERRORS;
                    608:        php_stream *stream;
                    609:        int size;
                    610:        long use_include_path = 0;
1.1       misho     611: 
1.1.1.2   misho     612:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &filename, &filename_len, &use_include_path) == FAILURE) {
                    613:                return;
                    614:        }
1.1       misho     615: 
1.1.1.2   misho     616:        if (use_include_path) {
                    617:                flags |= USE_PATH;
1.1       misho     618:        }
                    619: 
1.1.1.2   misho     620:        stream = php_stream_gzopen(NULL, filename, "rb", flags, NULL, NULL STREAMS_CC TSRMLS_CC);
                    621: 
                    622:        if (!stream) {
1.1       misho     623:                RETURN_FALSE;
                    624:        }
1.1.1.2   misho     625:        size = php_stream_passthru(stream);
                    626:        php_stream_close(stream);
                    627:        RETURN_LONG(size);
1.1       misho     628: }
                    629: /* }}} */
                    630: 
1.1.1.2   misho     631: #define PHP_ZLIB_ENCODE_FUNC(name, default_encoding) \
                    632: static PHP_FUNCTION(name) \
                    633: { \
                    634:        char *in_buf, *out_buf; \
                    635:        int in_len; \
                    636:        size_t out_len; \
                    637:        long level = -1; \
                    638:        long encoding = default_encoding; \
                    639:        if (default_encoding) { \
                    640:                if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &in_buf, &in_len, &level, &encoding)) { \
                    641:                        return; \
                    642:                } \
                    643:        } else { \
                    644:                if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &in_buf, &in_len, &encoding, &level)) { \
                    645:                        return; \
                    646:                } \
                    647:        } \
                    648:        if (level < -1 || level > 9) { \
                    649:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "compression level (%ld) must be within -1..9", level); \
                    650:                RETURN_FALSE; \
                    651:        } \
                    652:        switch (encoding) { \
                    653:                case PHP_ZLIB_ENCODING_RAW: \
                    654:                case PHP_ZLIB_ENCODING_GZIP: \
                    655:                case PHP_ZLIB_ENCODING_DEFLATE: \
                    656:                        break; \
                    657:                default: \
                    658:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "encoding mode must be either ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE"); \
                    659:                        RETURN_FALSE; \
                    660:        } \
                    661:        if (SUCCESS != php_zlib_encode(in_buf, in_len, &out_buf, &out_len, encoding, level TSRMLS_CC)) { \
                    662:                RETURN_FALSE; \
                    663:        } \
                    664:        RETURN_STRINGL(out_buf, out_len, 0); \
                    665: }
                    666: 
                    667: #define PHP_ZLIB_DECODE_FUNC(name, encoding) \
                    668: static PHP_FUNCTION(name) \
                    669: { \
                    670:        char *in_buf, *out_buf; \
                    671:        int in_len; \
                    672:        size_t out_len; \
                    673:        long max_len = 0; \
                    674:        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &in_buf, &in_len, &max_len)) { \
                    675:                return; \
                    676:        } \
                    677:        if (max_len < 0) { \
                    678:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "length (%ld) must be greater or equal zero", max_len); \
                    679:                RETURN_FALSE; \
                    680:        } \
                    681:        if (SUCCESS != php_zlib_decode(in_buf, in_len, &out_buf, &out_len, encoding, max_len TSRMLS_CC)) { \
                    682:                RETURN_FALSE; \
                    683:        } \
                    684:        RETURN_STRINGL(out_buf, out_len, 0); \
                    685: }
                    686: 
                    687: /* {{{ proto binary zlib_encode(binary data, int encoding[, int level = -1])
                    688:    Compress data with the specified encoding */
                    689: PHP_ZLIB_ENCODE_FUNC(zlib_encode, 0);
                    690: /* }}} */
                    691: 
                    692: /* {{{ proto binary zlib_decode(binary data[, int max_decoded_len])
                    693:    Uncompress any raw/gzip/zlib encoded data */
                    694: PHP_ZLIB_DECODE_FUNC(zlib_decode, PHP_ZLIB_ENCODING_ANY);
1.1.1.3 ! misho     695: /* }}} */
1.1.1.2   misho     696: 
                    697: /* NOTE: The naming of these userland functions was quite unlucky */
                    698: /* {{{ proto binary gzdeflate(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_RAW])
                    699:    Encode data with the raw deflate encoding */
                    700: PHP_ZLIB_ENCODE_FUNC(gzdeflate, PHP_ZLIB_ENCODING_RAW);
                    701: /* }}} */
                    702: 
                    703: /* {{{ proto binary gzencode(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_GZIP])
                    704:    Encode data with the gzip encoding */
                    705: PHP_ZLIB_ENCODE_FUNC(gzencode, PHP_ZLIB_ENCODING_GZIP);
                    706: /* }}} */
1.1.1.3 ! misho     707: 
1.1.1.2   misho     708: /* {{{ proto binary gzcompress(binary data[, int level = -1[, int encoding = ZLIB_ENCODING_DEFLATE])
                    709:    Encode data with the zlib encoding */
                    710: PHP_ZLIB_ENCODE_FUNC(gzcompress, PHP_ZLIB_ENCODING_DEFLATE);
                    711: /* }}} */
1.1.1.3 ! misho     712: 
1.1.1.2   misho     713: /* {{{ proto binary gzinflate(binary data[, int max_decoded_len])
                    714:    Decode raw deflate encoded data */
                    715: PHP_ZLIB_DECODE_FUNC(gzinflate, PHP_ZLIB_ENCODING_RAW);
                    716: /* }}} */
1.1.1.3 ! misho     717: 
1.1.1.2   misho     718: /* {{{ proto binary gzdecode(binary data[, int max_decoded_len])
                    719:    Decode gzip encoded data */
                    720: PHP_ZLIB_DECODE_FUNC(gzdecode, PHP_ZLIB_ENCODING_GZIP);
                    721: /* }}} */
1.1.1.3 ! misho     722: 
1.1.1.2   misho     723: /* {{{ proto binary gzuncompress(binary data[, int max_decoded_len])
                    724:    Decode zlib encoded data */
                    725: PHP_ZLIB_DECODE_FUNC(gzuncompress, PHP_ZLIB_ENCODING_DEFLATE);
                    726: /* }}} */
1.1       misho     727: 
1.1.1.2   misho     728: #ifdef COMPILE_DL_ZLIB
                    729: ZEND_GET_MODULE(php_zlib)
                    730: #endif
1.1       misho     731: 
1.1.1.2   misho     732: /* {{{ arginfo */
                    733: ZEND_BEGIN_ARG_INFO_EX(arginfo_ob_gzhandler, 0, 0, 2)
                    734:        ZEND_ARG_INFO(0, data)
                    735:        ZEND_ARG_INFO(0, flags)
                    736: ZEND_END_ARG_INFO()
1.1       misho     737: 
1.1.1.2   misho     738: ZEND_BEGIN_ARG_INFO(arginfo_zlib_get_coding_type, 0)
                    739: ZEND_END_ARG_INFO()
                    740: 
                    741: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzfile, 0, 0, 1)
                    742:        ZEND_ARG_INFO(0, filename)
                    743:        ZEND_ARG_INFO(0, use_include_path)
                    744: ZEND_END_ARG_INFO()
                    745: 
                    746: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzopen, 0, 0, 2)
                    747:        ZEND_ARG_INFO(0, filename)
                    748:        ZEND_ARG_INFO(0, mode)
                    749:        ZEND_ARG_INFO(0, use_include_path)
                    750: ZEND_END_ARG_INFO()
1.1       misho     751: 
1.1.1.2   misho     752: ZEND_BEGIN_ARG_INFO_EX(arginfo_readgzfile, 0, 0, 1)
                    753:        ZEND_ARG_INFO(0, filename)
                    754:        ZEND_ARG_INFO(0, use_include_path)
                    755: ZEND_END_ARG_INFO()
1.1       misho     756: 
1.1.1.2   misho     757: ZEND_BEGIN_ARG_INFO_EX(arginfo_zlib_encode, 0, 0, 2)
                    758:        ZEND_ARG_INFO(0, data)
                    759:        ZEND_ARG_INFO(0, encoding)
                    760:        ZEND_ARG_INFO(0, level)
                    761: ZEND_END_ARG_INFO()
1.1       misho     762: 
1.1.1.2   misho     763: ZEND_BEGIN_ARG_INFO_EX(arginfo_zlib_decode, 0, 0, 1)
                    764:        ZEND_ARG_INFO(0, data)
                    765:        ZEND_ARG_INFO(0, max_decoded_len)
                    766: ZEND_END_ARG_INFO()
1.1       misho     767: 
1.1.1.2   misho     768: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzdeflate, 0, 0, 1)
                    769:        ZEND_ARG_INFO(0, data)
                    770:        ZEND_ARG_INFO(0, level)
                    771:        ZEND_ARG_INFO(0, encoding)
                    772: ZEND_END_ARG_INFO()
1.1       misho     773: 
1.1.1.2   misho     774: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzencode, 0, 0, 1)
                    775:        ZEND_ARG_INFO(0, data)
                    776:        ZEND_ARG_INFO(0, level)
                    777:        ZEND_ARG_INFO(0, encoding)
                    778: ZEND_END_ARG_INFO()
1.1       misho     779: 
1.1.1.2   misho     780: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzcompress, 0, 0, 1)
                    781:        ZEND_ARG_INFO(0, data)
                    782:        ZEND_ARG_INFO(0, level)
                    783:        ZEND_ARG_INFO(0, encoding)
                    784: ZEND_END_ARG_INFO()
1.1       misho     785: 
1.1.1.2   misho     786: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzinflate, 0, 0, 1)
                    787:        ZEND_ARG_INFO(0, data)
                    788:        ZEND_ARG_INFO(0, max_decoded_len)
                    789: ZEND_END_ARG_INFO()
1.1       misho     790: 
1.1.1.2   misho     791: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzdecode, 0, 0, 1)
                    792:        ZEND_ARG_INFO(0, data)
                    793:        ZEND_ARG_INFO(0, max_decoded_len)
                    794: ZEND_END_ARG_INFO()
1.1       misho     795: 
1.1.1.2   misho     796: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzuncompress, 0, 0, 1)
                    797:        ZEND_ARG_INFO(0, data)
                    798:        ZEND_ARG_INFO(0, max_decoded_len)
                    799: ZEND_END_ARG_INFO()
1.1       misho     800: 
1.1.1.2   misho     801: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzputs, 0, 0, 2)
                    802:        ZEND_ARG_INFO(0, fp)
                    803:        ZEND_ARG_INFO(0, str)
                    804:        ZEND_ARG_INFO(0, length)
                    805: ZEND_END_ARG_INFO()
1.1       misho     806: 
1.1.1.2   misho     807: ZEND_BEGIN_ARG_INFO(arginfo_gzpassthru, 0)
                    808:        ZEND_ARG_INFO(0, fp)
                    809: ZEND_END_ARG_INFO()
1.1       misho     810: 
1.1.1.2   misho     811: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzseek, 0, 0, 2)
                    812:        ZEND_ARG_INFO(0, fp)
                    813:        ZEND_ARG_INFO(0, offset)
                    814:        ZEND_ARG_INFO(0, whence)
                    815: ZEND_END_ARG_INFO()
1.1       misho     816: 
1.1.1.2   misho     817: ZEND_BEGIN_ARG_INFO(arginfo_gzread, 0)
                    818:        ZEND_ARG_INFO(0, fp)
                    819:        ZEND_ARG_INFO(0, length)
                    820: ZEND_END_ARG_INFO()
1.1       misho     821: 
1.1.1.2   misho     822: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzgetss, 0, 0, 1)
                    823:        ZEND_ARG_INFO(0, fp)
                    824:        ZEND_ARG_INFO(0, length)
                    825:        ZEND_ARG_INFO(0, allowable_tags)
                    826: ZEND_END_ARG_INFO()
1.1       misho     827: 
1.1.1.2   misho     828: ZEND_BEGIN_ARG_INFO_EX(arginfo_gzgets, 0, 0, 1)
                    829:        ZEND_ARG_INFO(0, fp)
                    830:        ZEND_ARG_INFO(0, length)
                    831: ZEND_END_ARG_INFO()
1.1       misho     832: /* }}} */
                    833: 
1.1.1.2   misho     834: /* {{{ php_zlib_functions[] */
                    835: static const zend_function_entry php_zlib_functions[] = {
                    836:        PHP_FE(readgzfile,                                              arginfo_readgzfile)
                    837:        PHP_FALIAS(gzrewind,    rewind,                 arginfo_gzpassthru)
                    838:        PHP_FALIAS(gzclose,             fclose,                 arginfo_gzpassthru)
                    839:        PHP_FALIAS(gzeof,               feof,                   arginfo_gzpassthru)
                    840:        PHP_FALIAS(gzgetc,              fgetc,                  arginfo_gzpassthru)
                    841:        PHP_FALIAS(gzgets,              fgets,                  arginfo_gzgets)
                    842:        PHP_FALIAS(gzgetss,             fgetss,                 arginfo_gzgetss)
                    843:        PHP_FALIAS(gzread,              fread,                  arginfo_gzread)
                    844:        PHP_FE(gzopen,                                                  arginfo_gzopen)
                    845:        PHP_FALIAS(gzpassthru,  fpassthru,              arginfo_gzpassthru)
                    846:        PHP_FALIAS(gzseek,              fseek,                  arginfo_gzseek)
                    847:        PHP_FALIAS(gztell,              ftell,                  arginfo_gzpassthru)
                    848:        PHP_FALIAS(gzwrite,             fwrite,                 arginfo_gzputs)
                    849:        PHP_FALIAS(gzputs,              fwrite,                 arginfo_gzputs)
                    850:        PHP_FE(gzfile,                                                  arginfo_gzfile)
                    851:        PHP_FE(gzcompress,                                              arginfo_gzcompress)
                    852:        PHP_FE(gzuncompress,                                    arginfo_gzuncompress)
                    853:        PHP_FE(gzdeflate,                                               arginfo_gzdeflate)
                    854:        PHP_FE(gzinflate,                                               arginfo_gzinflate)
                    855:        PHP_FE(gzencode,                                                arginfo_gzencode)
                    856:        PHP_FE(gzdecode,                                                arginfo_gzdecode)
                    857:        PHP_FE(zlib_encode,                                             arginfo_zlib_encode)
                    858:        PHP_FE(zlib_decode,                                             arginfo_zlib_decode)
                    859:        PHP_FE(zlib_get_coding_type,                    arginfo_zlib_get_coding_type)
                    860:        PHP_FE(ob_gzhandler,                                    arginfo_ob_gzhandler)
                    861:        PHP_FE_END
                    862: };
                    863: /* }}} */
1.1       misho     864: 
1.1.1.2   misho     865: /* {{{ OnUpdate_zlib_output_compression */
                    866: static PHP_INI_MH(OnUpdate_zlib_output_compression)
                    867: {
                    868:        int status, int_value;
                    869:        char *ini_value;
1.1       misho     870: 
1.1.1.2   misho     871:        if (new_value == NULL) {
                    872:                return FAILURE;
1.1       misho     873:        }
                    874: 
1.1.1.2   misho     875:        if (!strncasecmp(new_value, "off", sizeof("off"))) {
                    876:                new_value = "0";
                    877:                new_value_length = sizeof("0");
                    878:        } else if (!strncasecmp(new_value, "on", sizeof("on"))) {
                    879:                new_value = "1";
                    880:                new_value_length = sizeof("1");
1.1       misho     881:        }
                    882: 
1.1.1.2   misho     883:        int_value = zend_atoi(new_value, new_value_length);
                    884:        ini_value = zend_ini_string("output_handler", sizeof("output_handler"), 0);
1.1       misho     885: 
1.1.1.2   misho     886:        if (ini_value && *ini_value && int_value) {
                    887:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_CORE_ERROR, "Cannot use both zlib.output_compression and output_handler together!!");
                    888:                return FAILURE;
1.1       misho     889:        }
1.1.1.2   misho     890:        if (stage == PHP_INI_STAGE_RUNTIME) {
                    891:                status = php_output_get_status(TSRMLS_C);
                    892:                if (status & PHP_OUTPUT_SENT) {
                    893:                        php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "Cannot change zlib.output_compression - headers already sent");
                    894:                        return FAILURE;
1.1       misho     895:                }
                    896:        }
                    897: 
1.1.1.2   misho     898:        status = OnUpdateLong(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
                    899: 
1.1.1.3 ! misho     900:        ZLIBG(output_compression) = ZLIBG(output_compression_default);
1.1.1.2   misho     901:        if (stage == PHP_INI_STAGE_RUNTIME && int_value) {
                    902:                if (!php_output_handler_started(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME) TSRMLS_CC)) {
                    903:                        php_zlib_output_compression_start(TSRMLS_C);
1.1       misho     904:                }
                    905:        }
1.1.1.2   misho     906: 
                    907:        return status;
1.1       misho     908: }
                    909: /* }}} */
                    910: 
1.1.1.2   misho     911: /* {{{ OnUpdate_zlib_output_handler */
                    912: static PHP_INI_MH(OnUpdate_zlib_output_handler)
1.1       misho     913: {
1.1.1.2   misho     914:        if (stage == PHP_INI_STAGE_RUNTIME && (php_output_get_status(TSRMLS_C) & PHP_OUTPUT_SENT)) {
                    915:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "Cannot change zlib.output_handler - headers already sent");
                    916:                return FAILURE;
1.1       misho     917:        }
                    918: 
1.1.1.2   misho     919:        return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
1.1       misho     920: }
1.1.1.2   misho     921: /* }}} */
                    922:  
                    923: /* {{{ INI */
                    924: PHP_INI_BEGIN()
1.1.1.3 ! misho     925:        STD_PHP_INI_BOOLEAN("zlib.output_compression",      "0", PHP_INI_ALL, OnUpdate_zlib_output_compression,       output_compression_default,       zend_zlib_globals, zlib_globals)
1.1.1.2   misho     926:        STD_PHP_INI_ENTRY("zlib.output_compression_level", "-1", PHP_INI_ALL, OnUpdateLong,                           output_compression_level, zend_zlib_globals, zlib_globals)
                    927:        STD_PHP_INI_ENTRY("zlib.output_handler",             "", PHP_INI_ALL, OnUpdate_zlib_output_handler,           output_handler,           zend_zlib_globals, zlib_globals)
                    928: PHP_INI_END()
1.1       misho     929: 
                    930: /* }}} */
                    931: 
1.1.1.2   misho     932: /* {{{ PHP_MINIT_FUNCTION */
                    933: static PHP_MINIT_FUNCTION(zlib)
1.1       misho     934: {
1.1.1.2   misho     935:        php_register_url_stream_wrapper("compress.zlib", &php_stream_gzip_wrapper TSRMLS_CC);
                    936:        php_stream_filter_register_factory("zlib.*", &php_zlib_filter_factory TSRMLS_CC);
1.1       misho     937: 
1.1.1.2   misho     938:        php_output_handler_alias_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_handler_init TSRMLS_CC);
                    939:        php_output_handler_conflict_register(ZEND_STRL("ob_gzhandler"), php_zlib_output_conflict_check TSRMLS_CC);
                    940:        php_output_handler_conflict_register(ZEND_STRL(PHP_ZLIB_OUTPUT_HANDLER_NAME), php_zlib_output_conflict_check TSRMLS_CC);
                    941: 
                    942:        REGISTER_LONG_CONSTANT("FORCE_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
                    943:        REGISTER_LONG_CONSTANT("FORCE_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
                    944: 
                    945:        REGISTER_LONG_CONSTANT("ZLIB_ENCODING_RAW", PHP_ZLIB_ENCODING_RAW, CONST_CS|CONST_PERSISTENT);
                    946:        REGISTER_LONG_CONSTANT("ZLIB_ENCODING_GZIP", PHP_ZLIB_ENCODING_GZIP, CONST_CS|CONST_PERSISTENT);
                    947:        REGISTER_LONG_CONSTANT("ZLIB_ENCODING_DEFLATE", PHP_ZLIB_ENCODING_DEFLATE, CONST_CS|CONST_PERSISTENT);
                    948:        REGISTER_INI_ENTRIES();
                    949:        return SUCCESS;
1.1       misho     950: }
                    951: /* }}} */
                    952: 
1.1.1.2   misho     953: /* {{{ PHP_MSHUTDOWN_FUNCTION */
                    954: static PHP_MSHUTDOWN_FUNCTION(zlib)
1.1       misho     955: {
1.1.1.2   misho     956:        php_unregister_url_stream_wrapper("zlib" TSRMLS_CC);
                    957:        php_stream_filter_unregister_factory("zlib.*" TSRMLS_CC);
1.1       misho     958: 
1.1.1.2   misho     959:        UNREGISTER_INI_ENTRIES();
1.1       misho     960: 
1.1.1.2   misho     961:        return SUCCESS;
1.1       misho     962: }
                    963: /* }}} */
                    964: 
1.1.1.2   misho     965: /* {{{ PHP_RINIT_FUNCTION */
                    966: static PHP_RINIT_FUNCTION(zlib)
1.1       misho     967: {
1.1.1.2   misho     968:        ZLIBG(compression_coding) = 0;
1.1.1.3 ! misho     969:     if (!ZLIBG(handler_registered)) {
        !           970:         ZLIBG(output_compression) = ZLIBG(output_compression_default);
        !           971:         php_zlib_output_compression_start(TSRMLS_C);
        !           972:     }
1.1       misho     973: 
1.1.1.2   misho     974:        return SUCCESS;
                    975: }
                    976: /* }}} */
1.1       misho     977: 
1.1.1.3 ! misho     978: /* {{{ PHP_RSHUTDOWN_FUNCTION */
1.1.1.2   misho     979: static PHP_RSHUTDOWN_FUNCTION(zlib)
                    980: {
                    981:        php_zlib_cleanup_ob_gzhandler_mess(TSRMLS_C);
1.1.1.3 ! misho     982:     ZLIBG(handler_registered) = 0;
1.1       misho     983: 
1.1.1.2   misho     984:     return SUCCESS;
                    985: }
1.1.1.3 ! misho     986: /* }}} */
1.1       misho     987: 
1.1.1.2   misho     988: /* {{{ PHP_MINFO_FUNCTION */
                    989: static PHP_MINFO_FUNCTION(zlib)
                    990: {
                    991:        php_info_print_table_start();
                    992:        php_info_print_table_header(2, "ZLib Support", "enabled");
                    993:        php_info_print_table_row(2, "Stream Wrapper", "compress.zlib://");
                    994:        php_info_print_table_row(2, "Stream Filter", "zlib.inflate, zlib.deflate");
                    995:        php_info_print_table_row(2, "Compiled Version", ZLIB_VERSION);
                    996:        php_info_print_table_row(2, "Linked Version", (char *) zlibVersion());
                    997:        php_info_print_table_end();
1.1       misho     998: 
1.1.1.2   misho     999:        DISPLAY_INI_ENTRIES();
1.1       misho    1000: }
                   1001: /* }}} */
                   1002: 
1.1.1.2   misho    1003: /* {{{ ZEND_MODULE_GLOBALS_CTOR */
                   1004: static ZEND_MODULE_GLOBALS_CTOR_D(zlib)
1.1       misho    1005: {
1.1.1.2   misho    1006:        zlib_globals->ob_gzhandler = NULL;
1.1.1.3 ! misho    1007:     zlib_globals->handler_registered = 0;
1.1       misho    1008: }
                   1009: /* }}} */
                   1010: 
1.1.1.2   misho    1011: /* {{{ php_zlib_module_entry */
                   1012: zend_module_entry php_zlib_module_entry = {
                   1013:        STANDARD_MODULE_HEADER,
                   1014:        "zlib",
                   1015:        php_zlib_functions,
                   1016:        PHP_MINIT(zlib),
                   1017:        PHP_MSHUTDOWN(zlib),
                   1018:        PHP_RINIT(zlib),
                   1019:        PHP_RSHUTDOWN(zlib),
                   1020:        PHP_MINFO(zlib),
                   1021:        "2.0",
                   1022:        PHP_MODULE_GLOBALS(zlib),
                   1023:        ZEND_MODULE_GLOBALS_CTOR_N(zlib),
                   1024:        NULL,
                   1025:        NULL,
                   1026:        STANDARD_MODULE_PROPERTIES_EX
                   1027: };
                   1028: /* }}} */
                   1029: 
1.1       misho    1030: /*
                   1031:  * Local variables:
                   1032:  * tab-width: 4
                   1033:  * c-basic-offset: 4
                   1034:  * End:
                   1035:  * vim600: sw=4 ts=4 fdm=marker
                   1036:  * vim<600: sw=4 ts=4
                   1037:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>