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>