diff options
| author | Mark Adler <madler@alumni.caltech.edu> | 2011-09-26 00:57:26 -0700 |
|---|---|---|
| committer | Mark Adler <madler@alumni.caltech.edu> | 2011-09-26 00:57:26 -0700 |
| commit | 5ad116abdad08c49b9ab20d748550eecd2c1d96d (patch) | |
| tree | 2aace8e541c2332df89f6161d98912258f23a637 | |
| parent | a9ae24b6538a8c75b13826ef8a2547344fd2e08c (diff) | |
| download | zlib-5ad116abdad08c49b9ab20d748550eecd2c1d96d.tar.gz zlib-5ad116abdad08c49b9ab20d748550eecd2c1d96d.tar.bz2 zlib-5ad116abdad08c49b9ab20d748550eecd2c1d96d.zip | |
Allow gzread() and related to continue after gzclearerr().
Before this fix, gzread() would lose data if a premature end of file
was encountered. This prevented gzread() from being used on a file
that was being written concurrently. Now gzread() returns all of the
data it has available before indicating a premature end of file.
This also changes the error returned on a premature end of file from
Z_DATA_ERROR to Z_BUF_ERROR. This allows the user to determine if
the error is recoverable, which it is if Z_BUF_ERROR is returned. If
a Z_DATA_ERROR is returned, then the error is not recoverable.
This patch replaces the functionality of a previous patch that fixed
reading through an empty gzip stream in a concatenation of gzip
streams.
To implement this fix, a noticeable rewrite of gzread.c was needed.
The patch has the added advantage of using inflate's gzip processing
instead of replicating the functionality in gzread.c. This makes the
gz code a little simpler.
| -rw-r--r-- | gzlib.c | 4 | ||||
| -rw-r--r-- | gzread.c | 268 |
2 files changed, 93 insertions, 179 deletions
| @@ -247,8 +247,8 @@ int ZEXPORT gzbuffer(file, size) | |||
| 247 | return -1; | 247 | return -1; |
| 248 | 248 | ||
| 249 | /* check and set requested size */ | 249 | /* check and set requested size */ |
| 250 | if (size == 0) | 250 | if (size < 2) |
| 251 | return -1; | 251 | size = 2; /* need two bytes to check magic header */ |
| 252 | state->want = size; | 252 | state->want = size; |
| 253 | return 0; | 253 | return 0; |
| 254 | } | 254 | } |
| @@ -8,10 +8,9 @@ | |||
| 8 | /* Local functions */ | 8 | /* Local functions */ |
| 9 | local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); | 9 | local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); |
| 10 | local int gz_avail OF((gz_statep)); | 10 | local int gz_avail OF((gz_statep)); |
| 11 | local int gz_next4 OF((gz_statep, unsigned long *)); | 11 | local int gz_look OF((gz_statep)); |
| 12 | local int gz_head OF((gz_statep)); | ||
| 13 | local int gz_decomp OF((gz_statep)); | 12 | local int gz_decomp OF((gz_statep)); |
| 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 | ||
| 17 | /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from | 16 | /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from |
| @@ -46,67 +45,42 @@ local int gz_load(state, buf, len, have) | |||
| 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 |
| 48 | that data has been used, no more attempts will be made to read the file. | 47 | that data has been used, no more attempts will be made to read the file. |
| 49 | gz_avail() assumes that strm->avail_in == 0. */ | 48 | If strm->avail_in != 0, then the current data is moved to the beginning of |
| 49 | the input buffer, and then the remainder of the buffer is loaded with the | ||
| 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; |
| 52 | { | 53 | { |
| 54 | unsigned got; | ||
| 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) |
| 56 | return -1; | 58 | return -1; |
| 57 | if (state->eof == 0) { | 59 | if (state->eof == 0) { |
| 58 | if (gz_load(state, state->in, state->size, | 60 | if (strm->avail_in) |
| 59 | (unsigned *)&(strm->avail_in)) == -1) | 61 | memmove(state->in, strm->next_in, strm->avail_in); |
| 62 | if (gz_load(state, state->in + strm->avail_in, | ||
| 63 | state->size - strm->avail_in, &got) == -1) | ||
| 60 | return -1; | 64 | return -1; |
| 65 | strm->avail_in += got; | ||
| 61 | strm->next_in = state->in; | 66 | strm->next_in = state->in; |
| 62 | } | 67 | } |
| 63 | return 0; | 68 | return 0; |
| 64 | } | 69 | } |
| 65 | 70 | ||
| 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; | ||
| 90 | } | ||
| 91 | |||
| 92 | /* Look for gzip header, set up for inflate or copy. state->have must be zero. | 71 | /* Look for gzip header, set up for inflate or copy. state->have must be zero. |
| 93 | If this is the first time in, allocate required memory. state->how will be | 72 | 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 | 73 | 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 | 74 | 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 | 75 | 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 | 76 | data from the input buffer will be copied to the output buffer. In that |
| 98 | copying, then leftover input data from the input buffer will be copied to | 77 | case, all further file reads will be directly to either the output buffer or |
| 99 | the output buffer. In that case, all further file reads will be directly to | 78 | a user buffer. If decompressing, the inflate state will be initialized. |
| 100 | either the output buffer or a user buffer. If decompressing, the inflate | 79 | gz_look() will return 0 on success or -1 on failure. */ |
| 101 | state and the check value will be initialized. gz_head() will return 0 on | 80 | local int gz_look(state) |
| 102 | success or -1 on failure. Failures may include read errors or gzip header | ||
| 103 | errors. */ | ||
| 104 | local int gz_head(state) | ||
| 105 | gz_statep state; | 81 | gz_statep state; |
| 106 | { | 82 | { |
| 107 | z_streamp strm = &(state->strm); | 83 | z_streamp strm = &(state->strm); |
| 108 | int flags; | ||
| 109 | unsigned len; | ||
| 110 | 84 | ||
| 111 | /* allocate read buffers and inflate memory */ | 85 | /* allocate read buffers and inflate memory */ |
| 112 | if (state->size == 0) { | 86 | if (state->size == 0) { |
| @@ -129,7 +103,7 @@ local int gz_head(state) | |||
| 129 | state->strm.opaque = Z_NULL; | 103 | state->strm.opaque = Z_NULL; |
| 130 | state->strm.avail_in = 0; | 104 | state->strm.avail_in = 0; |
| 131 | state->strm.next_in = Z_NULL; | 105 | state->strm.next_in = Z_NULL; |
| 132 | if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */ | 106 | if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ |
| 133 | free(state->out); | 107 | free(state->out); |
| 134 | free(state->in); | 108 | free(state->in); |
| 135 | state->size = 0; | 109 | state->size = 0; |
| @@ -138,73 +112,27 @@ local int gz_head(state) | |||
| 138 | } | 112 | } |
| 139 | } | 113 | } |
| 140 | 114 | ||
| 141 | /* get some data in the input buffer */ | 115 | /* get at least the magic bytes in the input buffer */ |
| 142 | if (strm->avail_in == 0) { | 116 | if (strm->avail_in < 2) { |
| 143 | if (gz_avail(state) == -1) | 117 | if (gz_avail(state) == -1) |
| 144 | return -1; | 118 | return -1; |
| 145 | if (strm->avail_in == 0) | 119 | if (strm->avail_in == 0) |
| 146 | return 0; | 120 | return 0; |
| 147 | } | 121 | } |
| 148 | 122 | ||
| 149 | /* look for the gzip magic header bytes 31 and 139 */ | 123 | /* look for gzip magic bytes -- if there, do gzip decoding (note: there is |
| 150 | if (strm->next_in[0] == 31) { | 124 | a logical dilemma here when considering the case of a partially written |
| 151 | strm->avail_in--; | 125 | gzip file, to wit, if a single 31 byte is written, then we cannot tell |
| 152 | strm->next_in++; | 126 | whether this is a single-byte file, or just a partially written gzip |
| 153 | if (strm->avail_in == 0 && gz_avail(state) == -1) | 127 | file -- for here we assume that if a gzip file is being written, then |
| 154 | return -1; | 128 | the header will be written in a single operation, so that reading a |
| 155 | if (strm->avail_in && strm->next_in[0] == 139) { | 129 | single byte is sufficient indication that it is not a gzip file) */ |
| 156 | /* we have a gzip header, woo hoo! */ | 130 | if (strm->avail_in > 1 && |
| 157 | strm->avail_in--; | 131 | strm->next_in[0] == 31 && strm->next_in[1] == 139) { |
| 158 | strm->next_in++; | 132 | inflateReset(strm); |
| 159 | 133 | state->how = GZIP; | |
| 160 | /* skip rest of header */ | 134 | state->direct = 0; |
| 161 | if (NEXT() != 8) { /* compression method */ | 135 | return 0; |
| 162 | gz_error(state, Z_DATA_ERROR, "unknown compression method"); | ||
| 163 | return -1; | ||
| 164 | } | ||
| 165 | flags = NEXT(); | ||
| 166 | if (flags & 0xe0) { /* reserved flag bits */ | ||
| 167 | gz_error(state, Z_DATA_ERROR, "unknown header flags set"); | ||
| 168 | return -1; | ||
| 169 | } | ||
| 170 | NEXT(); /* modification time */ | ||
| 171 | NEXT(); | ||
| 172 | NEXT(); | ||
| 173 | NEXT(); | ||
| 174 | NEXT(); /* extra flags */ | ||
| 175 | NEXT(); /* operating system */ | ||
| 176 | if (flags & 4) { /* extra field */ | ||
| 177 | len = (unsigned)NEXT(); | ||
| 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 | } | ||
| 193 | /* an unexpected end of file is not checked for here -- it will be | ||
| 194 | noticed on the first request for uncompressed data */ | ||
| 195 | |||
| 196 | /* set up for decompression */ | ||
| 197 | inflateReset(strm); | ||
| 198 | strm->adler = crc32(0L, Z_NULL, 0); | ||
| 199 | state->how = GZIP; | ||
| 200 | state->direct = 0; | ||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | else { | ||
| 204 | /* not a gzip file -- save first byte (31) and fall to raw i/o */ | ||
| 205 | state->out[0] = 31; | ||
| 206 | state->have = 1; | ||
| 207 | } | ||
| 208 | } | 136 | } |
| 209 | 137 | ||
| 210 | /* no gzip header -- if we were decoding gzip before, then this is trailing | 138 | /* no gzip header -- if we were decoding gzip before, then this is trailing |
| @@ -222,8 +150,8 @@ local int gz_head(state) | |||
| 222 | state->raw = state->pos; | 150 | state->raw = state->pos; |
| 223 | state->next = state->out; | 151 | state->next = state->out; |
| 224 | if (strm->avail_in) { | 152 | if (strm->avail_in) { |
| 225 | memcpy(state->next + state->have, strm->next_in, strm->avail_in); | 153 | memcpy(state->next, strm->next_in, strm->avail_in); |
| 226 | state->have += strm->avail_in; | 154 | state->have = strm->avail_in; |
| 227 | strm->avail_in = 0; | 155 | strm->avail_in = 0; |
| 228 | } | 156 | } |
| 229 | state->how = COPY; | 157 | state->how = COPY; |
| @@ -232,19 +160,15 @@ local int gz_head(state) | |||
| 232 | } | 160 | } |
| 233 | 161 | ||
| 234 | /* Decompress from input to the provided next_out and avail_out in the state. | 162 | /* Decompress from input to the provided next_out and avail_out in the state. |
| 235 | If the end of the compressed data is reached, then verify the gzip trailer | 163 | state->have and state->next are set to point to the just decompressed data, |
| 236 | check value and length (modulo 2^32). state->have and state->next are set | 164 | If the gzip stream completes, state->how is reset to LOOK to look for the |
| 237 | to point to the just decompressed data, and the crc is updated. If the | 165 | next gzip stream or raw data, once state->have is depleted. Returns 0 on |
| 238 | trailer is verified, state->how is reset to LOOK to look for the next gzip | 166 | success, -1 on failure. */ |
| 239 | stream or raw data, once state->have is depleted. Returns 0 on success, -1 | ||
| 240 | on failure. Failures may include invalid compressed data or a failed gzip | ||
| 241 | trailer verification. */ | ||
| 242 | local int gz_decomp(state) | 167 | local int gz_decomp(state) |
| 243 | gz_statep state; | 168 | gz_statep state; |
| 244 | { | 169 | { |
| 245 | int ret; | 170 | int ret = Z_OK; |
| 246 | unsigned had; | 171 | unsigned had; |
| 247 | unsigned long crc, len; | ||
| 248 | z_streamp strm = &(state->strm); | 172 | z_streamp strm = &(state->strm); |
| 249 | 173 | ||
| 250 | /* fill output buffer up to end of deflate stream */ | 174 | /* fill output buffer up to end of deflate stream */ |
| @@ -254,15 +178,15 @@ local int gz_decomp(state) | |||
| 254 | if (strm->avail_in == 0 && gz_avail(state) == -1) | 178 | if (strm->avail_in == 0 && gz_avail(state) == -1) |
| 255 | return -1; | 179 | return -1; |
| 256 | if (strm->avail_in == 0) { | 180 | if (strm->avail_in == 0) { |
| 257 | gz_error(state, Z_DATA_ERROR, "unexpected end of file"); | 181 | gz_error(state, Z_BUF_ERROR, "unexpected end of file"); |
| 258 | return -1; | 182 | break; |
| 259 | } | 183 | } |
| 260 | 184 | ||
| 261 | /* decompress and handle errors */ | 185 | /* decompress and handle errors */ |
| 262 | ret = inflate(strm, Z_NO_FLUSH); | 186 | ret = inflate(strm, Z_NO_FLUSH); |
| 263 | if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { | 187 | if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { |
| 264 | gz_error(state, Z_STREAM_ERROR, | 188 | gz_error(state, Z_STREAM_ERROR, |
| 265 | "internal error: inflate stream corrupt"); | 189 | "internal error: inflate stream corrupt"); |
| 266 | return -1; | 190 | return -1; |
| 267 | } | 191 | } |
| 268 | if (ret == Z_MEM_ERROR) { | 192 | if (ret == Z_MEM_ERROR) { |
| @@ -271,67 +195,55 @@ local int gz_decomp(state) | |||
| 271 | } | 195 | } |
| 272 | if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ | 196 | if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ |
| 273 | gz_error(state, Z_DATA_ERROR, | 197 | gz_error(state, Z_DATA_ERROR, |
| 274 | strm->msg == NULL ? "compressed data error" : strm->msg); | 198 | strm->msg == NULL ? "compressed data error" : strm->msg); |
| 275 | return -1; | 199 | return -1; |
| 276 | } | 200 | } |
| 277 | } while (strm->avail_out && ret != Z_STREAM_END); | 201 | } while (strm->avail_out && ret != Z_STREAM_END); |
| 278 | 202 | ||
| 279 | /* update available output and crc check value */ | 203 | /* update available output */ |
| 280 | state->have = had - strm->avail_out; | 204 | state->have = had - strm->avail_out; |
| 281 | state->next = strm->next_out - state->have; | 205 | state->next = strm->next_out - state->have; |
| 282 | strm->adler = crc32(strm->adler, state->next, state->have); | ||
| 283 | 206 | ||
| 284 | /* check gzip trailer if at end of deflate stream */ | 207 | /* if the gzip stream completed successfully, look for another */ |
| 285 | if (ret == Z_STREAM_END) { | 208 | if (ret == Z_STREAM_END) |
| 286 | if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) { | 209 | state->how = LOOK; |
| 287 | gz_error(state, Z_DATA_ERROR, "unexpected end of file"); | ||
| 288 | return -1; | ||
| 289 | } | ||
| 290 | if (crc != strm->adler) { | ||
| 291 | gz_error(state, Z_DATA_ERROR, "incorrect data check"); | ||
| 292 | return -1; | ||
| 293 | } | ||
| 294 | if (len != (strm->total_out & 0xffffffffL)) { | ||
| 295 | gz_error(state, Z_DATA_ERROR, "incorrect length check"); | ||
| 296 | return -1; | ||
| 297 | } | ||
| 298 | state->how = LOOK; /* ready for next stream, once have is 0 (leave | ||
| 299 | state->direct unchanged to remember how) */ | ||
| 300 | } | ||
| 301 | 210 | ||
| 302 | /* good decompression */ | 211 | /* good decompression */ |
| 303 | return 0; | 212 | return 0; |
| 304 | } | 213 | } |
| 305 | 214 | ||
| 306 | /* Make data and put in the output buffer. Assumes that state->have == 0. | 215 | /* Fetch data and put it in the output buffer. Assumes that state->have == 0. |
| 307 | Data is either copied from the input file or decompressed from the input | 216 | Data is either copied from the input file or decompressed from the input |
| 308 | file depending on state->how. If state->how is LOOK, then a gzip header is | 217 | file depending on state->how. If state->how is LOOK, then a gzip header is |
| 309 | looked for (and skipped if found) to discern whether to copy or decompress. | 218 | looked for to determine whether to copy or decompress. Returns -1 on error, |
| 310 | Returns -1 on error, otherwise 0. gz_make() will leave state->how as COPY | 219 | otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the |
| 311 | or GZIP unless the end of the input file has been reached and all data has | 220 | end of the input file has been reached and all data has been processed. */ |
| 312 | been processed. */ | 221 | local int gz_fetch(state) |
| 313 | local int gz_make(state) | ||
| 314 | gz_statep state; | 222 | gz_statep state; |
| 315 | { | 223 | { |
| 316 | z_streamp strm = &(state->strm); | 224 | z_streamp strm = &(state->strm); |
| 317 | 225 | ||
| 318 | if (state->how == LOOK) { /* look for gzip header */ | 226 | do { |
| 319 | if (gz_head(state) == -1) | 227 | switch(state->how) { |
| 320 | return -1; | 228 | case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ |
| 321 | if (state->have) /* got some data from gz_head() */ | 229 | if (gz_look(state) == -1) |
| 230 | return -1; | ||
| 231 | if (state->how == LOOK) | ||
| 232 | return 0; | ||
| 233 | break; | ||
| 234 | case COPY: /* -> COPY */ | ||
| 235 | if (gz_load(state, state->out, state->size << 1, &(state->have)) | ||
| 236 | == -1) | ||
| 237 | return -1; | ||
| 238 | state->next = state->out; | ||
| 322 | return 0; | 239 | return 0; |
| 323 | } | 240 | case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ |
| 324 | if (state->how == COPY) { /* straight copy */ | 241 | strm->avail_out = state->size << 1; |
| 325 | if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1) | 242 | strm->next_out = state->out; |
| 326 | return -1; | 243 | if (gz_decomp(state) == -1) |
| 327 | state->next = state->out; | 244 | return -1; |
| 328 | } | 245 | } |
| 329 | else if (state->how == GZIP) { /* decompress */ | 246 | } while (state->have == 0); |
| 330 | strm->avail_out = state->size << 1; | ||
| 331 | strm->next_out = state->out; | ||
| 332 | if (gz_decomp(state) == -1) | ||
| 333 | return -1; | ||
| 334 | } | ||
| 335 | return 0; | 247 | return 0; |
| 336 | } | 248 | } |
| 337 | 249 | ||
| @@ -361,7 +273,7 @@ local int gz_skip(state, len) | |||
| 361 | /* need more data to skip -- load up output buffer */ | 273 | /* need more data to skip -- load up output buffer */ |
| 362 | else { | 274 | else { |
| 363 | /* get more output, looking for header if required */ | 275 | /* get more output, looking for header if required */ |
| 364 | if (gz_make(state) == -1) | 276 | if (gz_fetch(state) == -1) |
| 365 | return -1; | 277 | return -1; |
| 366 | } | 278 | } |
| 367 | return 0; | 279 | return 0; |
| @@ -383,8 +295,9 @@ int ZEXPORT gzread(file, buf, len) | |||
| 383 | state = (gz_statep)file; | 295 | state = (gz_statep)file; |
| 384 | strm = &(state->strm); | 296 | strm = &(state->strm); |
| 385 | 297 | ||
| 386 | /* check that we're reading and that there's no error */ | 298 | /* check that we're reading and that there's no (serious) error */ |
| 387 | if (state->mode != GZ_READ || state->err != Z_OK) | 299 | if (state->mode != GZ_READ || |
| 300 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||
| 388 | return -1; | 301 | return -1; |
| 389 | 302 | ||
| 390 | /* since an int is returned, make sure len fits in one, otherwise return | 303 | /* since an int is returned, make sure len fits in one, otherwise return |
| @@ -424,7 +337,7 @@ int ZEXPORT gzread(file, buf, len) | |||
| 424 | buffer */ | 337 | buffer */ |
| 425 | else if (state->how == LOOK || len < (state->size << 1)) { | 338 | else if (state->how == LOOK || len < (state->size << 1)) { |
| 426 | /* get more output, looking for header if required */ | 339 | /* get more output, looking for header if required */ |
| 427 | if (gz_make(state) == -1) | 340 | if (gz_fetch(state) == -1) |
| 428 | return -1; | 341 | return -1; |
| 429 | continue; /* no progress yet -- go back to memcpy() above */ | 342 | continue; /* no progress yet -- go back to memcpy() above */ |
| 430 | /* the copy above assures that we will leave with space in the | 343 | /* the copy above assures that we will leave with space in the |
| @@ -471,8 +384,9 @@ int ZEXPORT gzgetc(file) | |||
| 471 | return -1; | 384 | return -1; |
| 472 | state = (gz_statep)file; | 385 | state = (gz_statep)file; |
| 473 | 386 | ||
| 474 | /* check that we're reading and that there's no error */ | 387 | /* check that we're reading and that there's no (serious) error */ |
| 475 | if (state->mode != GZ_READ || state->err != Z_OK) | 388 | if (state->mode != GZ_READ || |
| 389 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||
| 476 | return -1; | 390 | return -1; |
| 477 | 391 | ||
| 478 | /* try output buffer (no need to check for skip request) */ | 392 | /* try output buffer (no need to check for skip request) */ |
| @@ -499,8 +413,9 @@ int ZEXPORT gzungetc(c, file) | |||
| 499 | return -1; | 413 | return -1; |
| 500 | state = (gz_statep)file; | 414 | state = (gz_statep)file; |
| 501 | 415 | ||
| 502 | /* check that we're reading and that there's no error */ | 416 | /* check that we're reading and that there's no (serious) error */ |
| 503 | if (state->mode != GZ_READ || state->err != Z_OK) | 417 | if (state->mode != GZ_READ || |
| 418 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||
| 504 | return -1; | 419 | return -1; |
| 505 | 420 | ||
| 506 | /* process a skip request */ | 421 | /* process a skip request */ |
| @@ -560,8 +475,9 @@ char * ZEXPORT gzgets(file, buf, len) | |||
| 560 | return NULL; | 475 | return NULL; |
| 561 | state = (gz_statep)file; | 476 | state = (gz_statep)file; |
| 562 | 477 | ||
| 563 | /* check that we're reading and that there's no error */ | 478 | /* check that we're reading and that there's no (serious) error */ |
| 564 | if (state->mode != GZ_READ || state->err != Z_OK) | 479 | if (state->mode != GZ_READ || |
| 480 | (state->err != Z_OK && state->err != Z_BUF_ERROR)) | ||
| 565 | return NULL; | 481 | return NULL; |
| 566 | 482 | ||
| 567 | /* process a skip request */ | 483 | /* process a skip request */ |
| @@ -578,10 +494,8 @@ char * ZEXPORT gzgets(file, buf, len) | |||
| 578 | left = (unsigned)len - 1; | 494 | left = (unsigned)len - 1; |
| 579 | if (left) do { | 495 | if (left) do { |
| 580 | /* assure that something is in the output buffer */ | 496 | /* assure that something is in the output buffer */ |
| 581 | while (state->have == 0 && (state->strm.avail_in || !state->eof)) { | 497 | if (state->have == 0 && gz_fetch(state) == -1) |
| 582 | if (gz_make(state) == -1) | 498 | return NULL; /* error */ |
| 583 | return NULL; /* error */ | ||
| 584 | } | ||
| 585 | if (state->have == 0) { /* end of file */ | 499 | if (state->have == 0) { /* end of file */ |
| 586 | if (buf == str) /* got bupkus */ | 500 | if (buf == str) /* got bupkus */ |
| 587 | return NULL; | 501 | return NULL; |
| @@ -626,7 +540,7 @@ int ZEXPORT gzdirect(file) | |||
| 626 | /* if the state is not known, but we can find out, then do so (this is | 540 | /* if the state is not known, but we can find out, then do so (this is |
| 627 | mainly for right after a gzopen() or gzdopen()) */ | 541 | mainly for right after a gzopen() or gzdopen()) */ |
| 628 | if (state->how == LOOK && state->have == 0) | 542 | if (state->how == LOOK && state->have == 0) |
| 629 | (void)gz_head(state); | 543 | (void)gz_look(state); |
| 630 | 544 | ||
| 631 | /* return 1 if reading direct, 0 if decompressing a gzip stream */ | 545 | /* return 1 if reading direct, 0 if decompressing a gzip stream */ |
| 632 | return state->direct; | 546 | return state->direct; |
