Annotation of embedaddon/php/ext/zip/lib/zip_source_crc.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:   zip_source_crc.c -- pass-through source that calculates CRC32 and size
                      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 crc {
                     42:     int eof;
                     43:     int validate;
                     44:     int e[2];
                     45:     zip_uint64_t size;
                     46:     zip_uint32_t crc;
                     47: };
                     48: 
                     49: static zip_int64_t crc_read(struct zip_source *, void *, void *
                     50:                            , zip_uint64_t, enum zip_source_cmd);
                     51: 
                     52: 
                     53: 
                     54: ZIP_EXTERN(struct zip_source *)
                     55: zip_source_crc(struct zip *za, struct zip_source *src, int validate)
                     56: {
                     57:     struct crc *ctx;
                     58: 
                     59:     if (src == NULL) {
                     60:        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
                     61:        return NULL;
                     62:     }
                     63: 
                     64:     if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) {
                     65:        _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                     66:        return NULL;
                     67:     }
                     68: 
                     69:     ctx->validate = validate;
                     70: 
                     71:     return zip_source_layered(za, src, crc_read, ctx);
                     72: }
                     73: 
                     74: 
                     75: 
                     76: static zip_int64_t
                     77: crc_read(struct zip_source *src, void *_ctx, void *data,
                     78:         zip_uint64_t len, enum zip_source_cmd cmd)
                     79: {
                     80:     struct crc *ctx;
                     81:     zip_int64_t n;
                     82: 
                     83:     ctx = (struct crc *)_ctx;
                     84: 
                     85:     switch (cmd) {
                     86:     case ZIP_SOURCE_OPEN:
                     87:        ctx->eof = 0;
                     88:        ctx->crc = crc32(0, NULL, 0);
                     89:        ctx->size = 0;
                     90: 
                     91:        return 0;
                     92: 
                     93:     case ZIP_SOURCE_READ:
                     94:        if (ctx->eof || len == 0)
                     95:            return 0;
                     96: 
                     97:        if ((n=zip_source_read(src, data, len)) < 0)
                     98:            return ZIP_SOURCE_ERR_LOWER;
                     99: 
                    100:        if (n == 0) {
                    101:            ctx->eof = 1;
                    102:            if (ctx->validate) {
                    103:                struct zip_stat st;
                    104: 
                    105:                if (zip_source_stat(src, &st) < 0)
                    106:                    return ZIP_SOURCE_ERR_LOWER;
                    107: 
                    108:                if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
                    109:                    ctx->e[0] = ZIP_ER_CRC;
                    110:                    ctx->e[1] = 0;
                    111:                    
                    112:                    return -1;
                    113:                }
                    114:                if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
                    115:                    ctx->e[0] = ZIP_ER_INCONS;
                    116:                    ctx->e[1] = 0;
                    117:                    
                    118:                    return -1;
                    119:                }
                    120:            }
                    121:        }
                    122:        else {
                    123:            ctx->size += n;
                    124:            ctx->crc = crc32(ctx->crc, data, n);
                    125:        }
                    126:        return n;
                    127: 
                    128:     case ZIP_SOURCE_CLOSE:
                    129:        return 0;
                    130: 
                    131:     case ZIP_SOURCE_STAT:
                    132:        {
                    133:            struct zip_stat *st;
                    134: 
                    135:            st = (struct zip_stat *)data;
                    136: 
                    137:            if (ctx->eof) {
                    138:                /* XXX: Set comp_size, comp_method, encryption_method?
                    139:                        After all, this only works for uncompressed data. */
                    140:                st->size = ctx->size;
                    141:                st->crc = ctx->crc;
                    142:                st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC;
                    143:            }
                    144:        }
                    145:        return 0;
                    146:        
                    147:     case ZIP_SOURCE_ERROR:
                    148:        memcpy(data, ctx->e, sizeof(ctx->e));
                    149:        return 0;
                    150: 
                    151:     case ZIP_SOURCE_FREE:
                    152:        free(ctx);
                    153:        return 0;
                    154: 
                    155:     default:
                    156:        return -1;
                    157:     }
                    158:     
                    159: }

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