Annotation of embedaddon/php/ext/zip/lib/zip_source_deflate.c, revision 1.1

1.1     ! misho       1: /*
        !             2:   zip_source_deflate.c -- deflate (de)compressoin routines
        !             3:   Copyright (C) 2009 Dieter Baron and Thomas Klausner
        !             4: 
        !             5:   This file is part of libzip, a library to manipulate ZIP archives.
        !             6:   The authors can be contacted at <libzip@nih.at>
        !             7: 
        !             8:   Redistribution and use in source and binary forms, with or without
        !             9:   modification, are permitted provided that the following conditions
        !            10:   are met:
        !            11:   1. Redistributions of source code must retain the above copyright
        !            12:      notice, this list of conditions and the following disclaimer.
        !            13:   2. Redistributions in binary form must reproduce the above copyright
        !            14:      notice, this list of conditions and the following disclaimer in
        !            15:      the documentation and/or other materials provided with the
        !            16:      distribution.
        !            17:   3. The names of the authors may not be used to endorse or promote
        !            18:      products derived from this software without specific prior
        !            19:      written permission.
        !            20:  
        !            21:   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
        !            22:   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            23:   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
        !            25:   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
        !            27:   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            28:   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
        !            29:   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
        !            30:   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
        !            31:   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            32: */
        !            33: 
        !            34: 
        !            35: 
        !            36: #include <stdlib.h>
        !            37: #include <string.h>
        !            38: 
        !            39: #include "zipint.h"
        !            40: 
        !            41: struct deflate {
        !            42:     int e[2];
        !            43: 
        !            44:     int eof;
        !            45:     int mem_level;
        !            46:     zip_uint64_t size;
        !            47:     char buffer[BUFSIZE];
        !            48:     z_stream zstr;
        !            49: };
        !            50: 
        !            51: static zip_int64_t compress_read(struct zip_source *, struct deflate *,
        !            52:                                 void *, zip_uint64_t);
        !            53: static zip_int64_t decompress_read(struct zip_source *, struct deflate *,
        !            54:                                   void *, zip_uint64_t);
        !            55: static zip_int64_t deflate_compress(struct zip_source *, void *, void *,
        !            56:                                    zip_uint64_t, enum zip_source_cmd);
        !            57: static zip_int64_t deflate_decompress(struct zip_source *, void *, void *,
        !            58:                                      zip_uint64_t, enum zip_source_cmd);
        !            59: static void deflate_free(struct deflate *);
        !            60: 
        !            61: 
        !            62: 
        !            63: ZIP_EXTERN(struct zip_source *)
        !            64: zip_source_deflate(struct zip *za, struct zip_source *src,
        !            65:                   zip_uint16_t cm, int flags)
        !            66: {
        !            67:     struct deflate *ctx;
        !            68:     struct zip_source *s2;
        !            69: 
        !            70:     if (src == NULL || cm != ZIP_CM_DEFLATE) {
        !            71:        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
        !            72:        return NULL;
        !            73:     }
        !            74: 
        !            75:     if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
        !            76:        _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
        !            77:        return NULL;
        !            78:     }
        !            79: 
        !            80:     ctx->e[0] = ctx->e[1] = 0;
        !            81:     ctx->eof = 0;
        !            82:     if (flags & ZIP_CODEC_ENCODE) {
        !            83:        if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0))
        !            84:            ctx->mem_level = TORRENT_MEM_LEVEL;
        !            85:        else
        !            86:            ctx->mem_level = MAX_MEM_LEVEL;
        !            87:     }
        !            88: 
        !            89:     if ((s2=zip_source_layered(za, src,
        !            90:                               ((flags & ZIP_CODEC_ENCODE)
        !            91:                                ? deflate_compress : deflate_decompress),
        !            92:                               ctx)) == NULL) {
        !            93:        deflate_free(ctx);
        !            94:        return NULL;
        !            95:     }
        !            96: 
        !            97:     return s2;
        !            98: }
        !            99: 
        !           100: 
        !           101: 
        !           102: static zip_int64_t
        !           103: compress_read(struct zip_source *src, struct deflate *ctx,
        !           104:              void *data, zip_uint64_t len)
        !           105: {
        !           106:     int end, ret;
        !           107:     zip_int64_t n;
        !           108: 
        !           109:     if (ctx->e[0] != 0)
        !           110:        return -1;
        !           111:     
        !           112:     if (len == 0)
        !           113:        return 0;
        !           114:        
        !           115:     ctx->zstr.next_out = (Bytef *)data;
        !           116:     ctx->zstr.avail_out = len;
        !           117: 
        !           118:     end = 0;
        !           119:     while (!end) {
        !           120:        ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
        !           121: 
        !           122:        switch (ret) {
        !           123:        case Z_OK:
        !           124:        case Z_STREAM_END:
        !           125:            /* all ok */
        !           126: 
        !           127:            if (ctx->zstr.avail_out == 0
        !           128:                || (ctx->eof && ctx->zstr.avail_in == 0))
        !           129:                end = 1;
        !           130:            break;
        !           131: 
        !           132:        case Z_BUF_ERROR:
        !           133:            if (ctx->zstr.avail_in == 0) {
        !           134:                if (ctx->eof) {
        !           135:                    end = 1;
        !           136:                    break;
        !           137:                }
        !           138: 
        !           139:                if ((n=zip_source_read(src, ctx->buffer,
        !           140:                                       sizeof(ctx->buffer))) < 0) {
        !           141:                    zip_source_error(src, ctx->e, ctx->e+1);
        !           142:                    end = 1;
        !           143:                    break;
        !           144:                }
        !           145:                else if (n == 0) {
        !           146:                    ctx->eof = 1;
        !           147:                    ctx->size = ctx->zstr.total_in;
        !           148:                    /* XXX: check against stat of src? */
        !           149:                }
        !           150:                else {
        !           151:                    ctx->zstr.next_in = (Bytef *)ctx->buffer;
        !           152:                    ctx->zstr.avail_in = n;
        !           153:                }
        !           154:                continue;
        !           155:            }
        !           156:            /* fallthrough */
        !           157:        case Z_NEED_DICT:
        !           158:        case Z_DATA_ERROR:
        !           159:        case Z_STREAM_ERROR:
        !           160:        case Z_MEM_ERROR:
        !           161:            ctx->e[0] = ZIP_ER_ZLIB;
        !           162:            ctx->e[1] = ret;
        !           163: 
        !           164:            end = 1;
        !           165:            break;
        !           166:        }
        !           167:     }
        !           168: 
        !           169:     if (ctx->zstr.avail_out < len)
        !           170:        return len - ctx->zstr.avail_out;
        !           171: 
        !           172:     return (ctx->e[0] == 0) ? 0 : -1;
        !           173: }
        !           174: 
        !           175: 
        !           176: 
        !           177: static zip_int64_t
        !           178: decompress_read(struct zip_source *src, struct deflate *ctx,
        !           179:                void *data, zip_uint64_t len)
        !           180: {
        !           181:     int end, ret;
        !           182:     zip_int64_t n;
        !           183: 
        !           184:     if (ctx->e[0] != 0)
        !           185:        return -1;
        !           186:     
        !           187:     if (len == 0)
        !           188:        return 0;
        !           189:        
        !           190:     ctx->zstr.next_out = (Bytef *)data;
        !           191:     ctx->zstr.avail_out = len;
        !           192: 
        !           193:     end = 0;
        !           194:     while (!end && ctx->zstr.avail_out) {
        !           195:        ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
        !           196: 
        !           197:        switch (ret) {
        !           198:        case Z_OK:
        !           199:            break;
        !           200:            
        !           201:        case Z_STREAM_END:
        !           202:            ctx->eof = 1;
        !           203:            end = 1;
        !           204:            break;
        !           205: 
        !           206:        case Z_BUF_ERROR:
        !           207:            if (ctx->zstr.avail_in == 0) {
        !           208:                if (ctx->eof) {
        !           209:                    end = 1;
        !           210:                    break;
        !           211:                }
        !           212: 
        !           213:                if ((n=zip_source_read(src, ctx->buffer,
        !           214:                            sizeof(ctx->buffer))) < 0) {
        !           215:                    zip_source_error(src, ctx->e, ctx->e+1);
        !           216:                    end = 1;
        !           217:                    break;
        !           218:                }
        !           219:                else if (n == 0)
        !           220:                    ctx->eof = 1;
        !           221:                else {
        !           222:                    ctx->zstr.next_in = (Bytef *)ctx->buffer;
        !           223:                    ctx->zstr.avail_in = n;
        !           224:                }
        !           225:                continue;
        !           226:            }
        !           227:            /* fallthrough */
        !           228:        case Z_NEED_DICT:
        !           229:        case Z_DATA_ERROR:
        !           230:        case Z_STREAM_ERROR:
        !           231:        case Z_MEM_ERROR:
        !           232:            ctx->e[0] = ZIP_ER_ZLIB;
        !           233:            ctx->e[1] = ret;
        !           234:            end = 1;
        !           235:            break;
        !           236:        }
        !           237:     }
        !           238: 
        !           239:     if (ctx->zstr.avail_out < len)
        !           240:        return len - ctx->zstr.avail_out;
        !           241: 
        !           242:     return (ctx->e[0] == 0) ? 0 : -1;
        !           243: }
        !           244: 
        !           245: 
        !           246: 
        !           247: static zip_int64_t
        !           248: deflate_compress(struct zip_source *src, void *ud, void *data,
        !           249:                 zip_uint64_t len, enum zip_source_cmd cmd)
        !           250: {
        !           251:     struct deflate *ctx;
        !           252:     int ret;
        !           253: 
        !           254:     ctx = (struct deflate *)ud;
        !           255: 
        !           256:     switch (cmd) {
        !           257:     case ZIP_SOURCE_OPEN:
        !           258:        ctx->zstr.zalloc = Z_NULL;
        !           259:        ctx->zstr.zfree = Z_NULL;
        !           260:        ctx->zstr.opaque = NULL;
        !           261:        ctx->zstr.avail_in = 0;
        !           262:        ctx->zstr.next_in = NULL;
        !           263:        ctx->zstr.avail_out = 0;
        !           264:        ctx->zstr.next_out = NULL;
        !           265: 
        !           266:        /* negative value to tell zlib not to write a header */
        !           267:        if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED,
        !           268:                              -MAX_WBITS, ctx->mem_level,
        !           269:                              Z_DEFAULT_STRATEGY)) != Z_OK) {
        !           270:            ctx->e[0] = ZIP_ER_ZLIB;
        !           271:            ctx->e[1] = ret;
        !           272:            return -1;
        !           273:        }
        !           274: 
        !           275:        return 0;
        !           276: 
        !           277:     case ZIP_SOURCE_READ:
        !           278:        return compress_read(src, ctx, data, len);
        !           279: 
        !           280:     case ZIP_SOURCE_CLOSE:
        !           281:        deflateEnd(&ctx->zstr);
        !           282:        return 0;
        !           283: 
        !           284:     case ZIP_SOURCE_STAT:
        !           285:        {
        !           286:            struct zip_stat *st;
        !           287: 
        !           288:            st = (struct zip_stat *)data;
        !           289: 
        !           290:            st->comp_method = ZIP_CM_DEFLATE;
        !           291:            st->valid |= ZIP_STAT_COMP_METHOD;
        !           292:            if (ctx->eof) {
        !           293:                st->comp_size = ctx->size;
        !           294:                st->valid |= ZIP_STAT_COMP_SIZE;
        !           295:            }
        !           296:            else
        !           297:                st->valid &= ~ZIP_STAT_COMP_SIZE;
        !           298:        }
        !           299:        return 0;
        !           300: 
        !           301:     case ZIP_SOURCE_ERROR:
        !           302:        memcpy(data, ctx->e, sizeof(int)*2);
        !           303:        return sizeof(int)*2;
        !           304: 
        !           305:     case ZIP_SOURCE_FREE:
        !           306:        deflate_free(ctx);
        !           307:        return 0;
        !           308: 
        !           309:     default:
        !           310:        ctx->e[0] = ZIP_ER_INVAL;
        !           311:        ctx->e[1] = 0;
        !           312:        return -1;
        !           313:     }
        !           314: }
        !           315: 
        !           316: 
        !           317: 
        !           318: static zip_int64_t
        !           319: deflate_decompress(struct zip_source *src, void *ud, void *data,
        !           320:                   zip_uint64_t len, enum zip_source_cmd cmd)
        !           321: {
        !           322:     struct deflate *ctx;
        !           323:     zip_int64_t n;
        !           324:     int ret;
        !           325: 
        !           326:     ctx = (struct deflate *)ud;
        !           327: 
        !           328:     switch (cmd) {
        !           329:     case ZIP_SOURCE_OPEN:
        !           330:        if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0)
        !           331:            return ZIP_SOURCE_ERR_LOWER;
        !           332: 
        !           333:        ctx->zstr.zalloc = Z_NULL;
        !           334:        ctx->zstr.zfree = Z_NULL;
        !           335:        ctx->zstr.opaque = NULL;
        !           336:        ctx->zstr.next_in = (Bytef *)ctx->buffer;
        !           337:        ctx->zstr.avail_in = n;
        !           338: 
        !           339:        /* negative value to tell zlib that there is no header */
        !           340:        if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
        !           341:            ctx->e[0] = ZIP_ER_ZLIB;
        !           342:            ctx->e[1] = ret;
        !           343: 
        !           344:            return -1;
        !           345:        }
        !           346:        return 0;
        !           347: 
        !           348:     case ZIP_SOURCE_READ:
        !           349:        return decompress_read(src, ctx, data, len);
        !           350: 
        !           351:     case ZIP_SOURCE_CLOSE:
        !           352:        inflateEnd(&ctx->zstr);
        !           353:        return 0;
        !           354: 
        !           355:     case ZIP_SOURCE_STAT:
        !           356:        {
        !           357:            struct zip_stat *st;
        !           358: 
        !           359:            st = (struct zip_stat *)data;
        !           360: 
        !           361:            st->comp_method = ZIP_CM_STORE;
        !           362:            if (st->comp_size > 0 && st->size > 0)
        !           363:                st->comp_size = st->size;
        !           364:        }
        !           365:        return 0;
        !           366: 
        !           367:     case ZIP_SOURCE_ERROR:
        !           368:        if (len < sizeof(int)*2)
        !           369:            return -1;
        !           370: 
        !           371:        memcpy(data, ctx->e, sizeof(int)*2);
        !           372:        return sizeof(int)*2;
        !           373: 
        !           374:     case ZIP_SOURCE_FREE:
        !           375:        /* XXX: inflateEnd if close was not called */
        !           376:        free(ctx);
        !           377:        return 0;
        !           378: 
        !           379:     default:
        !           380:        ctx->e[0] = ZIP_ER_INVAL;
        !           381:        ctx->e[1] = 0;
        !           382:        return -1;
        !           383:     }
        !           384:     
        !           385: }
        !           386: 
        !           387: 
        !           388: 
        !           389: static void
        !           390: deflate_free(struct deflate *ctx)
        !           391: {
        !           392:     /* XXX: deflateEnd if close was not called */
        !           393:     free(ctx);
        !           394: }

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