Rev 1896 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1896 | Rev 3926 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* gzread.c -- zlib functions for reading gzip files |
1 | /* gzread.c -- zlib functions for reading gzip files |
2 | * Copyright (C) 2004, 2005, 2010 Mark Adler |
2 | * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler |
3 | * For conditions of distribution and use, see copyright notice in zlib.h |
3 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ |
4 | */ |
Line 5... | Line 5... | ||
5 | 5 | ||
Line 6... | Line 6... | ||
6 | #include "gzguts.h" |
6 | #include "gzguts.h" |
7 | 7 | ||
8 | /* Local functions */ |
8 | /* Local functions */ |
9 | local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); |
- | |
10 | local int gz_avail OF((gz_statep)); |
9 | local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); |
11 | local int gz_next4 OF((gz_statep, unsigned long *)); |
10 | local int gz_avail OF((gz_statep)); |
12 | local int gz_head OF((gz_statep)); |
11 | local int gz_look OF((gz_statep)); |
13 | local int gz_decomp OF((gz_statep)); |
12 | local int gz_decomp OF((gz_statep)); |
Line 14... | Line 13... | ||
14 | local int gz_make OF((gz_statep)); |
13 | local int gz_fetch OF((gz_statep)); |
15 | local int gz_skip OF((gz_statep, z_off64_t)); |
14 | local int gz_skip OF((gz_statep, z_off64_t)); |
16 | 15 | ||
Line 44... | Line 43... | ||
44 | 43 | ||
45 | /* Load up input buffer and set eof flag if last data loaded -- return -1 on |
44 | /* Load up input buffer and set eof flag if last data loaded -- return -1 on |
46 | error, 0 otherwise. Note that the eof flag is set when the end of the input |
45 | error, 0 otherwise. Note that the eof flag is set when the end of the input |
47 | file is reached, even though there may be unused data in the buffer. Once |
46 | file is reached, even though there may be unused data in the buffer. Once |
- | 47 | that data has been used, no more attempts will be made to read the file. |
|
- | 48 | If strm->avail_in != 0, then the current data is moved to the beginning of |
|
48 | that data has been used, no more attempts will be made to read the file. |
49 | the input buffer, and then the remainder of the buffer is loaded with the |
49 | gz_avail() assumes that strm->avail_in == 0. */ |
50 | available data from the input file. */ |
50 | local int gz_avail(state) |
51 | local int gz_avail(state) |
51 | gz_statep state; |
52 | gz_statep state; |
- | 53 | { |
|
52 | { |
54 | unsigned got; |
Line 53... | Line 55... | ||
53 | z_streamp strm = &(state->strm); |
55 | z_streamp strm = &(state->strm); |
54 | 56 | ||
55 | if (state->err != Z_OK) |
57 | if (state->err != Z_OK && state->err != Z_BUF_ERROR) |
- | 58 | return -1; |
|
- | 59 | if (state->eof == 0) { |
|
- | 60 | if (strm->avail_in) { /* copy what's there to the start */ |
|
- | 61 | unsigned char *p = state->in; |
|
- | 62 | unsigned const char *q = strm->next_in; |
|
- | 63 | unsigned n = strm->avail_in; |
|
- | 64 | do { |
|
- | 65 | *p++ = *q++; |
|
56 | return -1; |
66 | } while (--n); |
57 | if (state->eof == 0) { |
67 | } |
58 | if (gz_load(state, state->in, state->size, |
68 | if (gz_load(state, state->in + strm->avail_in, |
- | 69 | state->size - strm->avail_in, &got) == -1) |
|
59 | (unsigned *)&(strm->avail_in)) == -1) |
70 | return -1; |
60 | return -1; |
71 | strm->avail_in += got; |
61 | strm->next_in = state->in; |
72 | strm->next_in = state->in; |
62 | } |
73 | } |
Line 63... | Line -... | ||
63 | return 0; |
- | |
64 | } |
- | |
65 | - | ||
66 | /* Get next byte from input, or -1 if end or error. */ |
- | |
67 | #define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \ |
- | |
68 | (strm->avail_in == 0 ? -1 : \ |
- | |
69 | (strm->avail_in--, *(strm->next_in)++))) |
- | |
70 | - | ||
71 | /* Get a four-byte little-endian integer and return 0 on success and the value |
- | |
72 | in *ret. Otherwise -1 is returned and *ret is not modified. */ |
- | |
73 | local int gz_next4(state, ret) |
- | |
74 | gz_statep state; |
- | |
75 | unsigned long *ret; |
- | |
76 | { |
- | |
77 | int ch; |
- | |
78 | unsigned long val; |
- | |
79 | z_streamp strm = &(state->strm); |
- | |
80 | - | ||
81 | val = NEXT(); |
- | |
82 | val += (unsigned)NEXT() << 8; |
- | |
83 | val += (unsigned long)NEXT() << 16; |
- | |
84 | ch = NEXT(); |
- | |
85 | if (ch == -1) |
- | |
86 | return -1; |
- | |
87 | val += (unsigned long)ch << 24; |
- | |
88 | *ret = val; |
- | |
89 | return 0; |
74 | return 0; |
90 | } |
75 | } |
91 | 76 | ||
92 | /* Look for gzip header, set up for inflate or copy. state->have must be zero. |
77 | /* Look for gzip header, set up for inflate or copy. state->x.have must be 0. |
93 | If this is the first time in, allocate required memory. state->how will be |
78 | If this is the first time in, allocate required memory. state->how will be |
94 | left unchanged if there is no more input data available, will be set to COPY |
79 | left unchanged if there is no more input data available, will be set to COPY |
95 | if there is no gzip header and direct copying will be performed, or it will |
80 | if there is no gzip header and direct copying will be performed, or it will |
96 | be set to GZIP for decompression, and the gzip header will be skipped so |
81 | be set to GZIP for decompression. If direct copying, then leftover input |
97 | that the next available input data is the raw deflate stream. If direct |
- | |
98 | copying, then leftover input data from the input buffer will be copied to |
- | |
99 | the output buffer. In that case, all further file reads will be directly to |
82 | data from the input buffer will be copied to the output buffer. In that |
100 | either the output buffer or a user buffer. If decompressing, the inflate |
- | |
101 | state and the check value will be initialized. gz_head() will return 0 on |
83 | case, all further file reads will be directly to either the output buffer or |
102 | success or -1 on failure. Failures may include read errors or gzip header |
84 | a user buffer. If decompressing, the inflate state will be initialized. |
103 | errors. */ |
85 | gz_look() will return 0 on success or -1 on failure. */ |
104 | local int gz_head(state) |
86 | local int gz_look(state) |
105 | gz_statep state; |
- | |
106 | { |
- | |
Line 107... | Line 87... | ||
107 | z_streamp strm = &(state->strm); |
87 | gz_statep state; |
108 | int flags; |
88 | { |
109 | unsigned len; |
89 | z_streamp strm = &(state->strm); |
110 | 90 | ||
111 | /* allocate read buffers and inflate memory */ |
91 | /* allocate read buffers and inflate memory */ |
112 | if (state->size == 0) { |
92 | if (state->size == 0) { |
113 | /* allocate buffers */ |
93 | /* allocate buffers */ |
114 | state->in = malloc(state->want); |
94 | state->in = (unsigned char *)malloc(state->want); |
115 | state->out = malloc(state->want << 1); |
95 | state->out = (unsigned char *)malloc(state->want << 1); |
116 | if (state->in == NULL || state->out == NULL) { |
96 | if (state->in == NULL || state->out == NULL) { |
Line 127... | Line 107... | ||
127 | state->strm.zalloc = Z_NULL; |
107 | state->strm.zalloc = Z_NULL; |
128 | state->strm.zfree = Z_NULL; |
108 | state->strm.zfree = Z_NULL; |
129 | state->strm.opaque = Z_NULL; |
109 | state->strm.opaque = Z_NULL; |
130 | state->strm.avail_in = 0; |
110 | state->strm.avail_in = 0; |
131 | state->strm.next_in = Z_NULL; |
111 | state->strm.next_in = Z_NULL; |
132 | if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */ |
112 | if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ |
133 | free(state->out); |
113 | free(state->out); |
134 | free(state->in); |
114 | free(state->in); |
135 | state->size = 0; |
115 | state->size = 0; |
136 | gz_error(state, Z_MEM_ERROR, "out of memory"); |
116 | gz_error(state, Z_MEM_ERROR, "out of memory"); |
137 | return -1; |
117 | return -1; |
138 | } |
118 | } |
139 | } |
119 | } |
Line 140... | Line 120... | ||
140 | 120 | ||
141 | /* get some data in the input buffer */ |
121 | /* get at least the magic bytes in the input buffer */ |
142 | if (strm->avail_in == 0) { |
122 | if (strm->avail_in < 2) { |
143 | if (gz_avail(state) == -1) |
123 | if (gz_avail(state) == -1) |
144 | return -1; |
124 | return -1; |
145 | if (strm->avail_in == 0) |
125 | if (strm->avail_in == 0) |
146 | return 0; |
126 | return 0; |
Line 147... | Line 127... | ||
147 | } |
127 | } |
148 | - | ||
149 | /* look for the gzip magic header bytes 31 and 139 */ |
- | |
150 | if (strm->next_in[0] == 31) { |
- | |
151 | strm->avail_in--; |
- | |
152 | strm->next_in++; |
- | |
153 | if (strm->avail_in == 0 && gz_avail(state) == -1) |
- | |
154 | return -1; |
128 | |
155 | if (strm->avail_in && strm->next_in[0] == 139) { |
- | |
156 | /* we have a gzip header, woo hoo! */ |
- | |
157 | strm->avail_in--; |
- | |
158 | strm->next_in++; |
- | |
159 | 129 | /* look for gzip magic bytes -- if there, do gzip decoding (note: there is |
|
160 | /* skip rest of header */ |
- | |
161 | if (NEXT() != 8) { /* compression method */ |
- | |
162 | gz_error(state, Z_DATA_ERROR, "unknown compression method"); |
- | |
163 | return -1; |
- | |
164 | } |
130 | a logical dilemma here when considering the case of a partially written |
165 | flags = NEXT(); |
- | |
166 | if (flags & 0xe0) { /* reserved flag bits */ |
- | |
167 | gz_error(state, Z_DATA_ERROR, "unknown header flags set"); |
- | |
168 | return -1; |
131 | gzip file, to wit, if a single 31 byte is written, then we cannot tell |
169 | } |
- | |
170 | NEXT(); /* modification time */ |
- | |
171 | NEXT(); |
- | |
172 | NEXT(); |
- | |
173 | NEXT(); |
132 | whether this is a single-byte file, or just a partially written gzip |
174 | NEXT(); /* extra flags */ |
133 | file -- for here we assume that if a gzip file is being written, then |
175 | NEXT(); /* operating system */ |
- | |
176 | if (flags & 4) { /* extra field */ |
- | |
177 | len = (unsigned)NEXT(); |
134 | the header will be written in a single operation, so that reading a |
178 | len += (unsigned)NEXT() << 8; |
- | |
179 | while (len--) |
- | |
180 | if (NEXT() < 0) |
- | |
181 | break; |
- | |
182 | } |
- | |
183 | if (flags & 8) /* file name */ |
- | |
184 | while (NEXT() > 0) |
- | |
185 | ; |
- | |
186 | if (flags & 16) /* comment */ |
- | |
187 | while (NEXT() > 0) |
- | |
188 | ; |
- | |
189 | if (flags & 2) { /* header crc */ |
- | |
190 | NEXT(); |
- | |
191 | NEXT(); |
- | |
192 | } |
135 | single byte is sufficient indication that it is not a gzip file) */ |
193 | /* an unexpected end of file is not checked for here -- it will be |
- | |
194 | noticed on the first request for uncompressed data */ |
- | |
195 | 136 | if (strm->avail_in > 1 && |
|
196 | /* set up for decompression */ |
- | |
197 | inflateReset(strm); |
137 | strm->next_in[0] == 31 && strm->next_in[1] == 139) { |
198 | strm->adler = crc32(0L, Z_NULL, 0); |
138 | inflateReset(strm); |
199 | state->how = GZIP; |
139 | state->how = GZIP; |
200 | state->direct = 0; |
140 | state->direct = 0; |
- | 141 | return 0; |
|
- | 142 | } |
|
- | 143 | ||
201 | return 0; |
144 | /* no gzip header -- if we were decoding gzip before, then this is trailing |
202 | } |
145 | garbage. Ignore the trailing garbage and finish. */ |
203 | else { |
146 | if (state->direct == 0) { |
204 | /* not a gzip file -- save first byte (31) and fall to raw i/o */ |
147 | strm->avail_in = 0; |
205 | state->out[0] = 31; |
148 | state->eof = 1; |
206 | state->have = 1; |
149 | state->x.have = 0; |
Line 207... | Line 150... | ||
207 | } |
150 | return 0; |
208 | } |
151 | } |
209 | 152 | ||
210 | /* doing raw i/o, save start of raw data for seeking, copy any leftover |
- | |
211 | input to output -- this assumes that the output buffer is larger than |
153 | /* doing raw i/o, copy any leftover input to output -- this assumes that |
212 | the input buffer, which also assures space for gzungetc() */ |
154 | the output buffer is larger than the input buffer, which also assures |
213 | state->raw = state->pos; |
155 | space for gzungetc() */ |
214 | state->next = state->out; |
156 | state->x.next = state->out; |
215 | if (strm->avail_in) { |
157 | if (strm->avail_in) { |
216 | memcpy(state->next + state->have, strm->next_in, strm->avail_in); |
158 | memcpy(state->x.next, strm->next_in, strm->avail_in); |
217 | state->have += strm->avail_in; |
159 | state->x.have = strm->avail_in; |
218 | strm->avail_in = 0; |
160 | strm->avail_in = 0; |
219 | } |
161 | } |
220 | state->how = COPY; |
162 | state->how = COPY; |
Line 221... | Line 163... | ||
221 | state->direct = 1; |
163 | state->direct = 1; |
222 | return 0; |
- | |
223 | } |
164 | return 0; |
224 | - | ||
225 | /* Decompress from input to the provided next_out and avail_out in the state. |
165 | } |
226 | If the end of the compressed data is reached, then verify the gzip trailer |
166 | |
227 | check value and length (modulo 2^32). state->have and state->next are set |
- | |
228 | to point to the just decompressed data, and the crc is updated. If the |
167 | /* Decompress from input to the provided next_out and avail_out in the state. |
229 | trailer is verified, state->how is reset to LOOK to look for the next gzip |
168 | On return, state->x.have and state->x.next point to the just decompressed |
230 | stream or raw data, once state->have is depleted. Returns 0 on success, -1 |
169 | data. If the gzip stream completes, state->how is reset to LOOK to look for |
231 | on failure. Failures may include invalid compressed data or a failed gzip |
170 | the next gzip stream or raw data, once state->x.have is depleted. Returns 0 |
232 | trailer verification. */ |
171 | on success, -1 on failure. */ |
233 | local int gz_decomp(state) |
172 | local int gz_decomp(state) |
234 | gz_statep state; |
- | |
235 | { |
173 | gz_statep state; |
Line 236... | Line 174... | ||
236 | int ret; |
174 | { |
237 | unsigned had; |
175 | int ret = Z_OK; |
238 | unsigned long crc, len; |
176 | unsigned had; |
239 | z_streamp strm = &(state->strm); |
177 | z_streamp strm = &(state->strm); |
240 | 178 | ||
241 | /* fill output buffer up to end of deflate stream */ |
179 | /* fill output buffer up to end of deflate stream */ |
242 | had = strm->avail_out; |
180 | had = strm->avail_out; |
243 | do { |
181 | do { |
244 | /* get more input for inflate() */ |
182 | /* get more input for inflate() */ |
245 | if (strm->avail_in == 0 && gz_avail(state) == -1) |
183 | if (strm->avail_in == 0 && gz_avail(state) == -1) |
Line 246... | Line 184... | ||
246 | return -1; |
184 | return -1; |
247 | if (strm->avail_in == 0) { |
185 | if (strm->avail_in == 0) { |
248 | gz_error(state, Z_DATA_ERROR, "unexpected end of file"); |
186 | gz_error(state, Z_BUF_ERROR, "unexpected end of file"); |
Line 265... | Line 203... | ||
265 | strm->msg == NULL ? "compressed data error" : strm->msg); |
203 | strm->msg == NULL ? "compressed data error" : strm->msg); |
266 | return -1; |
204 | return -1; |
267 | } |
205 | } |
268 | } while (strm->avail_out && ret != Z_STREAM_END); |
206 | } while (strm->avail_out && ret != Z_STREAM_END); |
Line 269... | Line 207... | ||
269 | 207 | ||
270 | /* update available output and crc check value */ |
208 | /* update available output */ |
271 | state->have = had - strm->avail_out; |
209 | state->x.have = had - strm->avail_out; |
272 | state->next = strm->next_out - state->have; |
- | |
273 | strm->adler = crc32(strm->adler, state->next, state->have); |
210 | state->x.next = strm->next_out - state->x.have; |
274 | 211 | ||
275 | /* check gzip trailer if at end of deflate stream */ |
212 | /* if the gzip stream completed successfully, look for another */ |
276 | if (ret == Z_STREAM_END) { |
- | |
277 | if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) { |
- | |
278 | gz_error(state, Z_DATA_ERROR, "unexpected end of file"); |
- | |
279 | return -1; |
- | |
280 | } |
- | |
281 | if (crc != strm->adler) { |
- | |
282 | gz_error(state, Z_DATA_ERROR, "incorrect data check"); |
- | |
283 | return -1; |
- | |
284 | } |
- | |
285 | if (len != (strm->total_out & 0xffffffffL)) { |
- | |
286 | gz_error(state, Z_DATA_ERROR, "incorrect length check"); |
213 | if (ret == Z_STREAM_END) |
287 | return -1; |
- | |
288 | } |
- | |
289 | state->how = LOOK; /* ready for next stream, once have is 0 (leave |
- | |
290 | state->direct unchanged to remember how) */ |
- | |
Line 291... | Line 214... | ||
291 | } |
214 | state->how = LOOK; |
292 | 215 | ||
293 | /* good decompression */ |
216 | /* good decompression */ |
Line 294... | Line 217... | ||
294 | return 0; |
217 | return 0; |
295 | } |
218 | } |
296 | 219 | ||
297 | /* Make data and put in the output buffer. Assumes that state->have == 0. |
220 | /* Fetch data and put it in the output buffer. Assumes state->x.have is 0. |
298 | Data is either copied from the input file or decompressed from the input |
221 | Data is either copied from the input file or decompressed from the input |
299 | file depending on state->how. If state->how is LOOK, then a gzip header is |
222 | file depending on state->how. If state->how is LOOK, then a gzip header is |
300 | looked for (and skipped if found) to determine wither to copy or decompress. |
- | |
301 | Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY |
223 | looked for to determine whether to copy or decompress. Returns -1 on error, |
302 | or GZIP unless the end of the input file has been reached and all data has |
224 | otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the |
303 | been processed. */ |
225 | end of the input file has been reached and all data has been processed. */ |
304 | local int gz_make(state) |
226 | local int gz_fetch(state) |
Line -... | Line 227... | ||
- | 227 | gz_statep state; |
|
- | 228 | { |
|
305 | gz_statep state; |
229 | z_streamp strm = &(state->strm); |
306 | { |
230 | |
307 | z_streamp strm = &(state->strm); |
231 | do { |
308 | 232 | switch(state->how) { |
|
309 | if (state->how == LOOK) { /* look for gzip header */ |
233 | case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ |
310 | if (gz_head(state) == -1) |
234 | if (gz_look(state) == -1) |
311 | return -1; |
235 | return -1; |
312 | if (state->have) /* got some data from gz_head() */ |
236 | if (state->how == LOOK) |
- | 237 | return 0; |
|
313 | return 0; |
238 | break; |
314 | } |
239 | case COPY: /* -> COPY */ |
315 | if (state->how == COPY) { /* straight copy */ |
240 | if (gz_load(state, state->out, state->size << 1, &(state->x.have)) |
316 | if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1) |
241 | == -1) |
317 | return -1; |
242 | return -1; |
318 | state->next = state->out; |
243 | state->x.next = state->out; |
319 | } |
244 | return 0; |
320 | else if (state->how == GZIP) { /* decompress */ |
245 | case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ |
321 | strm->avail_out = state->size << 1; |
246 | strm->avail_out = state->size << 1; |
- | 247 | strm->next_out = state->out; |
|
322 | strm->next_out = state->out; |
248 | if (gz_decomp(state) == -1) |
323 | if (gz_decomp(state) == -1) |
249 | return -1; |
Line 324... | Line 250... | ||
324 | return -1; |
250 | } |
325 | } |
251 | } while (state->x.have == 0 && (!state->eof || strm->avail_in)); |
Line 334... | Line 260... | ||
334 | unsigned n; |
260 | unsigned n; |
Line 335... | Line 261... | ||
335 | 261 | ||
336 | /* skip over len bytes or reach end-of-file, whichever comes first */ |
262 | /* skip over len bytes or reach end-of-file, whichever comes first */ |
337 | while (len) |
263 | while (len) |
338 | /* skip over whatever is in output buffer */ |
264 | /* skip over whatever is in output buffer */ |
339 | if (state->have) { |
265 | if (state->x.have) { |
340 | n = GT_OFF(state->have) || (z_off64_t)state->have > len ? |
266 | n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? |
341 | (unsigned)len : state->have; |
267 | (unsigned)len : state->x.have; |
342 | state->have -= n; |
268 | state->x.have -= n; |
343 | state->next += n; |
269 | state->x.next += n; |
344 | state->pos += n; |
270 | state->x.pos += n; |
345 | len -= n; |
271 | len -= n; |
Line 346... | Line 272... | ||
346 | } |
272 | } |
347 | 273 | ||
348 | /* output buffer empty -- return if we're at the end of the input */ |
274 | /* output buffer empty -- return if we're at the end of the input */ |
Line 349... | Line 275... | ||
349 | else if (state->eof && state->strm.avail_in == 0) |
275 | else if (state->eof && state->strm.avail_in == 0) |
350 | break; |
276 | break; |
351 | 277 | ||
352 | /* need more data to skip -- load up output buffer */ |
278 | /* need more data to skip -- load up output buffer */ |
353 | else { |
279 | else { |
354 | /* get more output, looking for header if required */ |
280 | /* get more output, looking for header if required */ |
355 | if (gz_make(state) == -1) |
281 | if (gz_fetch(state) == -1) |
356 | return -1; |
282 | return -1; |
Line 372... | Line 298... | ||
372 | if (file == NULL) |
298 | if (file == NULL) |
373 | return -1; |
299 | return -1; |
374 | state = (gz_statep)file; |
300 | state = (gz_statep)file; |
375 | strm = &(state->strm); |
301 | strm = &(state->strm); |
Line 376... | Line 302... | ||
376 | 302 | ||
377 | /* check that we're reading and that there's no error */ |
303 | /* check that we're reading and that there's no (serious) error */ |
- | 304 | if (state->mode != GZ_READ || |
|
378 | if (state->mode != GZ_READ || state->err != Z_OK) |
305 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) |
Line 379... | Line 306... | ||
379 | return -1; |
306 | return -1; |
380 | 307 | ||
381 | /* since an int is returned, make sure len fits in one, otherwise return |
308 | /* since an int is returned, make sure len fits in one, otherwise return |
382 | with an error (this avoids the flaw in the interface) */ |
309 | with an error (this avoids the flaw in the interface) */ |
383 | if ((int)len < 0) { |
310 | if ((int)len < 0) { |
384 | gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); |
311 | gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); |
Line 385... | Line 312... | ||
385 | return -1; |
312 | return -1; |
386 | } |
313 | } |
Line 398... | Line 325... | ||
398 | 325 | ||
399 | /* get len bytes to buf, or less than len if at the end */ |
326 | /* get len bytes to buf, or less than len if at the end */ |
400 | got = 0; |
327 | got = 0; |
401 | do { |
328 | do { |
402 | /* first just try copying data from the output buffer */ |
329 | /* first just try copying data from the output buffer */ |
403 | if (state->have) { |
330 | if (state->x.have) { |
404 | n = state->have > len ? len : state->have; |
331 | n = state->x.have > len ? len : state->x.have; |
405 | memcpy(buf, state->next, n); |
332 | memcpy(buf, state->x.next, n); |
406 | state->next += n; |
333 | state->x.next += n; |
407 | state->have -= n; |
334 | state->x.have -= n; |
Line 408... | Line 335... | ||
408 | } |
335 | } |
409 | 336 | ||
- | 337 | /* output buffer empty -- return if we're at the end of the input */ |
|
410 | /* output buffer empty -- return if we're at the end of the input */ |
338 | else if (state->eof && strm->avail_in == 0) { |
- | 339 | state->past = 1; /* tried to read past end */ |
|
Line 411... | Line 340... | ||
411 | else if (state->eof && strm->avail_in == 0) |
340 | break; |
412 | break; |
341 | } |
413 | 342 | ||
414 | /* need output data -- for small len or new stream load up our output |
343 | /* need output data -- for small len or new stream load up our output |
415 | buffer */ |
344 | buffer */ |
416 | else if (state->how == LOOK || len < (state->size << 1)) { |
345 | else if (state->how == LOOK || len < (state->size << 1)) { |
417 | /* get more output, looking for header if required */ |
346 | /* get more output, looking for header if required */ |
418 | if (gz_make(state) == -1) |
347 | if (gz_fetch(state) == -1) |
419 | return -1; |
348 | return -1; |
420 | continue; /* no progress yet -- go back to memcpy() above */ |
349 | continue; /* no progress yet -- go back to copy above */ |
Line 421... | Line 350... | ||
421 | /* the copy above assures that we will leave with space in the |
350 | /* the copy above assures that we will leave with space in the |
422 | output buffer, allowing at least one gzungetc() to succeed */ |
351 | output buffer, allowing at least one gzungetc() to succeed */ |
423 | } |
352 | } |
424 | 353 | ||
425 | /* large len -- read directly into user buffer */ |
354 | /* large len -- read directly into user buffer */ |
Line 426... | Line 355... | ||
426 | else if (state->how == COPY) { /* read directly */ |
355 | else if (state->how == COPY) { /* read directly */ |
427 | if (gz_load(state, buf, len, &n) == -1) |
356 | if (gz_load(state, (unsigned char *)buf, len, &n) == -1) |
428 | return -1; |
357 | return -1; |
429 | } |
358 | } |
430 | 359 | ||
431 | /* large len -- decompress directly into user buffer */ |
360 | /* large len -- decompress directly into user buffer */ |
432 | else { /* state->how == GZIP */ |
361 | else { /* state->how == GZIP */ |
433 | strm->avail_out = len; |
362 | strm->avail_out = len; |
434 | strm->next_out = buf; |
363 | strm->next_out = (unsigned char *)buf; |
Line 435... | Line 364... | ||
435 | if (gz_decomp(state) == -1) |
364 | if (gz_decomp(state) == -1) |
436 | return -1; |
365 | return -1; |
437 | n = state->have; |
366 | n = state->x.have; |
438 | state->have = 0; |
367 | state->x.have = 0; |
439 | } |
368 | } |
440 | 369 | ||
Line 441... | Line 370... | ||
441 | /* update progress */ |
370 | /* update progress */ |
442 | len -= n; |
371 | len -= n; |
443 | buf = (char *)buf + n; |
372 | buf = (char *)buf + n; |
Line 444... | Line 373... | ||
444 | got += n; |
373 | got += n; |
- | 374 | state->x.pos += n; |
|
- | 375 | } while (len); |
|
- | 376 | ||
- | 377 | /* return number of bytes read into user buffer (will fit in int) */ |
|
- | 378 | return (int)got; |
|
445 | state->pos += n; |
379 | } |
446 | } while (len); |
380 | |
447 | 381 | /* -- see zlib.h -- */ |
|
448 | /* return number of bytes read into user buffer (will fit in int) */ |
382 | #ifdef Z_PREFIX_SET |
449 | return (int)got; |
383 | # undef z_gzgetc |
Line 460... | Line 394... | ||
460 | /* get internal structure */ |
394 | /* get internal structure */ |
461 | if (file == NULL) |
395 | if (file == NULL) |
462 | return -1; |
396 | return -1; |
463 | state = (gz_statep)file; |
397 | state = (gz_statep)file; |
Line 464... | Line 398... | ||
464 | 398 | ||
- | 399 | /* check that we're reading and that there's no (serious) error */ |
|
465 | /* check that we're reading and that there's no error */ |
400 | if (state->mode != GZ_READ || |
466 | if (state->mode != GZ_READ || state->err != Z_OK) |
401 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) |
Line 467... | Line 402... | ||
467 | return -1; |
402 | return -1; |
468 | 403 | ||
469 | /* try output buffer (no need to check for skip request) */ |
404 | /* try output buffer (no need to check for skip request) */ |
470 | if (state->have) { |
405 | if (state->x.have) { |
471 | state->have--; |
406 | state->x.have--; |
472 | state->pos++; |
407 | state->x.pos++; |
Line 473... | Line 408... | ||
473 | return *(state->next)++; |
408 | return *(state->x.next)++; |
474 | } |
409 | } |
475 | 410 | ||
476 | /* nothing there -- try gzread() */ |
411 | /* nothing there -- try gzread() */ |
Line -... | Line 412... | ||
- | 412 | ret = gzread(file, buf, 1); |
|
- | 413 | return ret < 1 ? -1 : buf[0]; |
|
- | 414 | } |
|
- | 415 | ||
- | 416 | int ZEXPORT gzgetc_(file) |
|
- | 417 | gzFile file; |
|
477 | ret = gzread(file, buf, 1); |
418 | { |
478 | return ret < 1 ? -1 : buf[0]; |
419 | return gzgetc(file); |
479 | } |
420 | } |
480 | 421 | ||
481 | /* -- see zlib.h -- */ |
422 | /* -- see zlib.h -- */ |
Line 488... | Line 429... | ||
488 | /* get internal structure */ |
429 | /* get internal structure */ |
489 | if (file == NULL) |
430 | if (file == NULL) |
490 | return -1; |
431 | return -1; |
491 | state = (gz_statep)file; |
432 | state = (gz_statep)file; |
Line 492... | Line 433... | ||
492 | 433 | ||
- | 434 | /* check that we're reading and that there's no (serious) error */ |
|
493 | /* check that we're reading and that there's no error */ |
435 | if (state->mode != GZ_READ || |
494 | if (state->mode != GZ_READ || state->err != Z_OK) |
436 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) |
Line 495... | Line 437... | ||
495 | return -1; |
437 | return -1; |
496 | 438 | ||
497 | /* process a skip request */ |
439 | /* process a skip request */ |
Line 504... | Line 446... | ||
504 | /* can't push EOF */ |
446 | /* can't push EOF */ |
505 | if (c < 0) |
447 | if (c < 0) |
506 | return -1; |
448 | return -1; |
Line 507... | Line 449... | ||
507 | 449 | ||
508 | /* if output buffer empty, put byte at end (allows more pushing) */ |
450 | /* if output buffer empty, put byte at end (allows more pushing) */ |
509 | if (state->have == 0) { |
451 | if (state->x.have == 0) { |
510 | state->have = 1; |
452 | state->x.have = 1; |
511 | state->next = state->out + (state->size << 1) - 1; |
453 | state->x.next = state->out + (state->size << 1) - 1; |
512 | state->next[0] = c; |
454 | state->x.next[0] = c; |
- | 455 | state->x.pos--; |
|
513 | state->pos--; |
456 | state->past = 0; |
514 | return c; |
457 | return c; |
Line 515... | Line 458... | ||
515 | } |
458 | } |
516 | 459 | ||
517 | /* if no room, give up (must have already done a gzungetc()) */ |
460 | /* if no room, give up (must have already done a gzungetc()) */ |
518 | if (state->have == (state->size << 1)) { |
461 | if (state->x.have == (state->size << 1)) { |
519 | gz_error(state, Z_BUF_ERROR, "out of room to push characters"); |
462 | gz_error(state, Z_DATA_ERROR, "out of room to push characters"); |
Line 520... | Line 463... | ||
520 | return -1; |
463 | return -1; |
521 | } |
464 | } |
522 | 465 | ||
523 | /* slide output data if needed and insert byte before existing data */ |
466 | /* slide output data if needed and insert byte before existing data */ |
524 | if (state->next == state->out) { |
467 | if (state->x.next == state->out) { |
525 | unsigned char *src = state->out + state->have; |
468 | unsigned char *src = state->out + state->x.have; |
526 | unsigned char *dest = state->out + (state->size << 1); |
469 | unsigned char *dest = state->out + (state->size << 1); |
527 | while (src > state->out) |
470 | while (src > state->out) |
528 | *--dest = *--src; |
471 | *--dest = *--src; |
529 | state->next = dest; |
472 | state->x.next = dest; |
530 | } |
473 | } |
531 | state->have++; |
474 | state->x.have++; |
- | 475 | state->x.next--; |
|
532 | state->next--; |
476 | state->x.next[0] = c; |
533 | state->next[0] = c; |
477 | state->x.pos--; |
Line 534... | Line 478... | ||
534 | state->pos--; |
478 | state->past = 0; |
535 | return c; |
479 | return c; |
Line 549... | Line 493... | ||
549 | /* check parameters and get internal structure */ |
493 | /* check parameters and get internal structure */ |
550 | if (file == NULL || buf == NULL || len < 1) |
494 | if (file == NULL || buf == NULL || len < 1) |
551 | return NULL; |
495 | return NULL; |
552 | state = (gz_statep)file; |
496 | state = (gz_statep)file; |
Line 553... | Line 497... | ||
553 | 497 | ||
- | 498 | /* check that we're reading and that there's no (serious) error */ |
|
554 | /* check that we're reading and that there's no error */ |
499 | if (state->mode != GZ_READ || |
555 | if (state->mode != GZ_READ || state->err != Z_OK) |
500 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) |
Line 556... | Line 501... | ||
556 | return NULL; |
501 | return NULL; |
557 | 502 | ||
558 | /* process a skip request */ |
503 | /* process a skip request */ |
Line 567... | Line 512... | ||
567 | the contents, let the user worry about that) */ |
512 | the contents, let the user worry about that) */ |
568 | str = buf; |
513 | str = buf; |
569 | left = (unsigned)len - 1; |
514 | left = (unsigned)len - 1; |
570 | if (left) do { |
515 | if (left) do { |
571 | /* assure that something is in the output buffer */ |
516 | /* assure that something is in the output buffer */ |
572 | if (state->have == 0) { |
- | |
573 | if (gz_make(state) == -1) |
517 | if (state->x.have == 0 && gz_fetch(state) == -1) |
574 | return NULL; /* error */ |
518 | return NULL; /* error */ |
575 | if (state->have == 0) { /* end of file */ |
519 | if (state->x.have == 0) { /* end of file */ |
576 | if (buf == str) /* got bupkus */ |
520 | state->past = 1; /* read past end */ |
577 | return NULL; |
- | |
578 | break; /* got something -- return it */ |
521 | break; /* return what we have */ |
579 | } |
- | |
580 | } |
522 | } |
Line 581... | Line 523... | ||
581 | 523 | ||
582 | /* look for end-of-line in current output buffer */ |
524 | /* look for end-of-line in current output buffer */ |
583 | n = state->have > left ? left : state->have; |
525 | n = state->x.have > left ? left : state->x.have; |
584 | eol = memchr(state->next, '\n', n); |
526 | eol = (unsigned char *)memchr(state->x.next, '\n', n); |
585 | if (eol != NULL) |
527 | if (eol != NULL) |
Line 586... | Line 528... | ||
586 | n = (unsigned)(eol - state->next) + 1; |
528 | n = (unsigned)(eol - state->x.next) + 1; |
587 | 529 | ||
588 | /* copy through end-of-line, or remainder if not found */ |
530 | /* copy through end-of-line, or remainder if not found */ |
589 | memcpy(buf, state->next, n); |
531 | memcpy(buf, state->x.next, n); |
590 | state->have -= n; |
532 | state->x.have -= n; |
591 | state->next += n; |
533 | state->x.next += n; |
592 | state->pos += n; |
534 | state->x.pos += n; |
593 | left -= n; |
535 | left -= n; |
Line 594... | Line 536... | ||
594 | buf += n; |
536 | buf += n; |
- | 537 | } while (left && eol == NULL); |
|
- | 538 | ||
595 | } while (left && eol == NULL); |
539 | /* return terminated string, or if nothing, end of file */ |
596 | 540 | if (buf == str) |
|
597 | /* found end-of-line or out of space -- terminate string and return it */ |
541 | return NULL; |
Line 598... | Line 542... | ||
598 | buf[0] = 0; |
542 | buf[0] = 0; |
Line 608... | Line 552... | ||
608 | /* get internal structure */ |
552 | /* get internal structure */ |
609 | if (file == NULL) |
553 | if (file == NULL) |
610 | return 0; |
554 | return 0; |
611 | state = (gz_statep)file; |
555 | state = (gz_statep)file; |
Line 612... | Line -... | ||
612 | - | ||
613 | /* check that we're reading */ |
- | |
614 | if (state->mode != GZ_READ) |
- | |
615 | return 0; |
- | |
616 | 556 | ||
617 | /* if the state is not known, but we can find out, then do so (this is |
557 | /* if the state is not known, but we can find out, then do so (this is |
618 | mainly for right after a gzopen() or gzdopen()) */ |
558 | mainly for right after a gzopen() or gzdopen()) */ |
619 | if (state->how == LOOK && state->have == 0) |
559 | if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) |
Line 620... | Line 560... | ||
620 | (void)gz_head(state); |
560 | (void)gz_look(state); |
621 | 561 | ||
622 | /* return 1 if reading direct, 0 if decompressing a gzip stream */ |
562 | /* return 1 if transparent, 0 if processing a gzip stream */ |
Line 623... | Line 563... | ||
623 | return state->direct; |
563 | return state->direct; |
624 | } |
564 | } |
625 | 565 | ||
626 | /* -- see zlib.h -- */ |
566 | /* -- see zlib.h -- */ |
627 | int ZEXPORT gzclose_r(file) |
567 | int ZEXPORT gzclose_r(file) |
628 | gzFile file; |
568 | gzFile file; |
Line 629... | Line 569... | ||
629 | { |
569 | { |
630 | int ret; |
570 | int ret, err; |
631 | gz_statep state; |
571 | gz_statep state; |
Line 643... | Line 583... | ||
643 | if (state->size) { |
583 | if (state->size) { |
644 | inflateEnd(&(state->strm)); |
584 | inflateEnd(&(state->strm)); |
645 | free(state->out); |
585 | free(state->out); |
646 | free(state->in); |
586 | free(state->in); |
647 | } |
587 | } |
- | 588 | err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; |
|
648 | gz_error(state, Z_OK, NULL); |
589 | gz_error(state, Z_OK, NULL); |
649 | free(state->path); |
590 | free(state->path); |
650 | ret = close(state->fd); |
591 | ret = close(state->fd); |
651 | free(state); |
592 | free(state); |
652 | return ret ? Z_ERRNO : Z_OK; |
593 | return ret ? Z_ERRNO : err; |
653 | }>><>><>><>>>><>>>><>><>>><>><>><>><>><>>>=> |
594 | }>><>><>><>>>><>>>><>><>>><>>>=> |