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

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

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