/src/skia/third_party/externals/freetype/src/gzip/inflate.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* inflate.c -- zlib interface to inflate modules |
2 | | * Copyright (C) 1995-2002 Mark Adler |
3 | | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | | */ |
5 | | |
6 | | #include "zutil.h" |
7 | | #include "infblock.h" |
8 | | |
9 | 0 | #define DONE INFLATE_DONE |
10 | 0 | #define BAD INFLATE_BAD |
11 | | |
12 | | typedef enum { |
13 | | METHOD, /* waiting for method byte */ |
14 | | FLAG, /* waiting for flag byte */ |
15 | | DICT4, /* four dictionary check bytes to go */ |
16 | | DICT3, /* three dictionary check bytes to go */ |
17 | | DICT2, /* two dictionary check bytes to go */ |
18 | | DICT1, /* one dictionary check byte to go */ |
19 | | DICT0, /* waiting for inflateSetDictionary */ |
20 | | BLOCKS, /* decompressing blocks */ |
21 | | CHECK4, /* four check bytes to go */ |
22 | | CHECK3, /* three check bytes to go */ |
23 | | CHECK2, /* two check bytes to go */ |
24 | | CHECK1, /* one check byte to go */ |
25 | | DONE, /* finished check, done */ |
26 | | BAD} /* got an error--stay here */ |
27 | | inflate_mode; |
28 | | |
29 | | /* inflate private state */ |
30 | | struct internal_state { |
31 | | |
32 | | /* mode */ |
33 | | inflate_mode mode; /* current inflate mode */ |
34 | | |
35 | | /* mode dependent information */ |
36 | | union { |
37 | | uInt method; /* if FLAGS, method byte */ |
38 | | struct { |
39 | | uLong was; /* computed check value */ |
40 | | uLong need; /* stream check value */ |
41 | | } check; /* if CHECK, check values to compare */ |
42 | | uInt marker; /* if BAD, inflateSync's marker bytes count */ |
43 | | } sub; /* submode */ |
44 | | |
45 | | /* mode independent information */ |
46 | | int nowrap; /* flag for no wrapper */ |
47 | | uInt wbits; /* log2(window size) (8..15, defaults to 15) */ |
48 | | inflate_blocks_statef |
49 | | *blocks; /* current inflate_blocks state */ |
50 | | |
51 | | }; |
52 | | |
53 | | |
54 | | ZEXPORT(int) inflateReset( /* z) */ |
55 | | z_streamp z ) |
56 | 0 | { |
57 | 0 | if (z == Z_NULL || z->state == Z_NULL) |
58 | 0 | return Z_STREAM_ERROR; |
59 | 0 | z->total_in = z->total_out = 0; |
60 | 0 | z->msg = Z_NULL; |
61 | 0 | z->state->mode = z->state->nowrap ? BLOCKS : METHOD; |
62 | 0 | inflate_blocks_reset(z->state->blocks, z, Z_NULL); |
63 | 0 | Tracev((stderr, "inflate: reset\n")); |
64 | 0 | return Z_OK; |
65 | 0 | } |
66 | | |
67 | | |
68 | | ZEXPORT(int) inflateEnd( /* z) */ |
69 | | z_streamp z ) |
70 | 0 | { |
71 | 0 | if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) |
72 | 0 | return Z_STREAM_ERROR; |
73 | 0 | if (z->state->blocks != Z_NULL) |
74 | 0 | inflate_blocks_free(z->state->blocks, z); |
75 | 0 | ZFREE(z, z->state); |
76 | 0 | z->state = Z_NULL; |
77 | 0 | Tracev((stderr, "inflate: end\n")); |
78 | 0 | return Z_OK; |
79 | 0 | } |
80 | | |
81 | | |
82 | | ZEXPORT(int) inflateInit2_( /* z, w, version, stream_size) */ |
83 | | z_streamp z, |
84 | | int w, |
85 | | const char *version, |
86 | | int stream_size ) |
87 | 0 | { |
88 | 0 | if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || |
89 | 0 | stream_size != sizeof(z_stream)) |
90 | 0 | return Z_VERSION_ERROR; |
91 | | |
92 | | /* initialize state */ |
93 | 0 | if (z == Z_NULL) |
94 | 0 | return Z_STREAM_ERROR; |
95 | 0 | z->msg = Z_NULL; |
96 | 0 | if (z->zalloc == Z_NULL) |
97 | 0 | { |
98 | 0 | z->zalloc = zcalloc; |
99 | 0 | z->opaque = (voidpf)0; |
100 | 0 | } |
101 | 0 | if (z->zfree == Z_NULL) z->zfree = zcfree; |
102 | 0 | if ((z->state = (struct internal_state FAR *) |
103 | 0 | ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) |
104 | 0 | return Z_MEM_ERROR; |
105 | 0 | z->state->blocks = Z_NULL; |
106 | | |
107 | | /* handle undocumented nowrap option (no zlib header or check) */ |
108 | 0 | z->state->nowrap = 0; |
109 | 0 | if (w < 0) |
110 | 0 | { |
111 | 0 | w = - w; |
112 | 0 | z->state->nowrap = 1; |
113 | 0 | } |
114 | | |
115 | | /* set window size */ |
116 | 0 | if (w < 8 || w > 15) |
117 | 0 | { |
118 | 0 | inflateEnd(z); |
119 | 0 | return Z_STREAM_ERROR; |
120 | 0 | } |
121 | 0 | z->state->wbits = (uInt)w; |
122 | | |
123 | | /* create inflate_blocks state */ |
124 | 0 | if ((z->state->blocks = |
125 | 0 | inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) |
126 | 0 | == Z_NULL) |
127 | 0 | { |
128 | 0 | inflateEnd(z); |
129 | 0 | return Z_MEM_ERROR; |
130 | 0 | } |
131 | 0 | Tracev((stderr, "inflate: allocated\n")); |
132 | | |
133 | | /* reset state */ |
134 | 0 | inflateReset(z); |
135 | 0 | return Z_OK; |
136 | 0 | } |
137 | | |
138 | | |
139 | | |
140 | | #undef NEEDBYTE |
141 | 0 | #define NEEDBYTE {if(z->avail_in==0)return r;r=f;} |
142 | | |
143 | | #undef NEXTBYTE |
144 | 0 | #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) |
145 | | |
146 | | |
147 | | ZEXPORT(int) inflate( /* z, f) */ |
148 | | z_streamp z, |
149 | | int f ) |
150 | 0 | { |
151 | 0 | int r; |
152 | 0 | uInt b; |
153 | |
|
154 | 0 | if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) |
155 | 0 | return Z_STREAM_ERROR; |
156 | 0 | f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; |
157 | 0 | r = Z_BUF_ERROR; |
158 | 0 | while (1) switch (z->state->mode) |
159 | 0 | { |
160 | 0 | case METHOD: |
161 | 0 | NEEDBYTE |
162 | 0 | if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) |
163 | 0 | { |
164 | 0 | z->state->mode = BAD; |
165 | 0 | z->msg = (char*)"unknown compression method"; |
166 | 0 | z->state->sub.marker = 5; /* can't try inflateSync */ |
167 | 0 | break; |
168 | 0 | } |
169 | 0 | if ((z->state->sub.method >> 4) + 8 > z->state->wbits) |
170 | 0 | { |
171 | 0 | z->state->mode = BAD; |
172 | 0 | z->msg = (char*)"invalid window size"; |
173 | 0 | z->state->sub.marker = 5; /* can't try inflateSync */ |
174 | 0 | break; |
175 | 0 | } |
176 | 0 | z->state->mode = FLAG; |
177 | | /* fall through */ |
178 | 0 | case FLAG: |
179 | 0 | NEEDBYTE |
180 | 0 | b = NEXTBYTE; |
181 | 0 | if (((z->state->sub.method << 8) + b) % 31) |
182 | 0 | { |
183 | 0 | z->state->mode = BAD; |
184 | 0 | z->msg = (char*)"incorrect header check"; |
185 | 0 | z->state->sub.marker = 5; /* can't try inflateSync */ |
186 | 0 | break; |
187 | 0 | } |
188 | 0 | Tracev((stderr, "inflate: zlib header ok\n")); |
189 | 0 | if (!(b & PRESET_DICT)) |
190 | 0 | { |
191 | 0 | z->state->mode = BLOCKS; |
192 | 0 | break; |
193 | 0 | } |
194 | 0 | z->state->mode = DICT4; |
195 | | /* fall through */ |
196 | 0 | case DICT4: |
197 | 0 | NEEDBYTE |
198 | 0 | z->state->sub.check.need = (uLong)NEXTBYTE << 24; |
199 | 0 | z->state->mode = DICT3; |
200 | | /* fall through */ |
201 | 0 | case DICT3: |
202 | 0 | NEEDBYTE |
203 | 0 | z->state->sub.check.need += (uLong)NEXTBYTE << 16; |
204 | 0 | z->state->mode = DICT2; |
205 | | /* fall through */ |
206 | 0 | case DICT2: |
207 | 0 | NEEDBYTE |
208 | 0 | z->state->sub.check.need += (uLong)NEXTBYTE << 8; |
209 | 0 | z->state->mode = DICT1; |
210 | | /* fall through */ |
211 | 0 | case DICT1: |
212 | 0 | NEEDBYTE |
213 | 0 | z->state->sub.check.need += (uLong)NEXTBYTE; |
214 | 0 | z->adler = z->state->sub.check.need; |
215 | 0 | z->state->mode = DICT0; |
216 | 0 | return Z_NEED_DICT; |
217 | 0 | case DICT0: |
218 | 0 | z->state->mode = BAD; |
219 | 0 | z->msg = (char*)"need dictionary"; |
220 | 0 | z->state->sub.marker = 0; /* can try inflateSync */ |
221 | 0 | return Z_STREAM_ERROR; |
222 | 0 | case BLOCKS: |
223 | 0 | r = inflate_blocks(z->state->blocks, z, r); |
224 | 0 | if (r == Z_DATA_ERROR) |
225 | 0 | { |
226 | 0 | z->state->mode = BAD; |
227 | 0 | z->state->sub.marker = 0; /* can try inflateSync */ |
228 | 0 | break; |
229 | 0 | } |
230 | 0 | if (r == Z_OK) |
231 | 0 | r = f; |
232 | 0 | if (r != Z_STREAM_END) |
233 | 0 | return r; |
234 | 0 | r = f; |
235 | 0 | inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); |
236 | 0 | if (z->state->nowrap) |
237 | 0 | { |
238 | 0 | z->state->mode = DONE; |
239 | 0 | break; |
240 | 0 | } |
241 | 0 | z->state->mode = CHECK4; |
242 | | /* fall through */ |
243 | 0 | case CHECK4: |
244 | 0 | NEEDBYTE |
245 | 0 | z->state->sub.check.need = (uLong)NEXTBYTE << 24; |
246 | 0 | z->state->mode = CHECK3; |
247 | | /* fall through */ |
248 | 0 | case CHECK3: |
249 | 0 | NEEDBYTE |
250 | 0 | z->state->sub.check.need += (uLong)NEXTBYTE << 16; |
251 | 0 | z->state->mode = CHECK2; |
252 | | /* fall through */ |
253 | 0 | case CHECK2: |
254 | 0 | NEEDBYTE |
255 | 0 | z->state->sub.check.need += (uLong)NEXTBYTE << 8; |
256 | 0 | z->state->mode = CHECK1; |
257 | | /* fall through */ |
258 | 0 | case CHECK1: |
259 | 0 | NEEDBYTE |
260 | 0 | z->state->sub.check.need += (uLong)NEXTBYTE; |
261 | |
|
262 | 0 | if (z->state->sub.check.was != z->state->sub.check.need) |
263 | 0 | { |
264 | 0 | z->state->mode = BAD; |
265 | 0 | z->msg = (char*)"incorrect data check"; |
266 | 0 | z->state->sub.marker = 5; /* can't try inflateSync */ |
267 | 0 | break; |
268 | 0 | } |
269 | 0 | Tracev((stderr, "inflate: zlib check ok\n")); |
270 | 0 | z->state->mode = DONE; |
271 | | /* fall through */ |
272 | 0 | case DONE: |
273 | 0 | return Z_STREAM_END; |
274 | 0 | case BAD: |
275 | 0 | return Z_DATA_ERROR; |
276 | 0 | default: |
277 | 0 | return Z_STREAM_ERROR; |
278 | 0 | } |
279 | | #ifdef NEED_DUMMY_RETURN |
280 | | return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ |
281 | | #endif |
282 | 0 | } |
283 | | |