X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=gzread.c;h=bf4538eb274245ad118edd3eaac38ee9e697c2b5;hb=0b166094092efa2b92200cbb67f390e86c181ab4;hp=22eb6271a1534002f96ff68a8bc9b21613a3e6ed;hpb=acfc85772a811f4c0efec835a3087b53f83f6079;p=zlib.git diff --git a/gzread.c b/gzread.c index 22eb627..bf4538e 100644 --- a/gzread.c +++ b/gzread.c @@ -1,5 +1,5 @@ /* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010 Mark Adler + * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -57,8 +57,14 @@ local int gz_avail(state) if (state->err != Z_OK && state->err != Z_BUF_ERROR) return -1; if (state->eof == 0) { - if (strm->avail_in) - memmove(state->in, strm->next_in, strm->avail_in); + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } if (gz_load(state, state->in + strm->avail_in, state->size - strm->avail_in, &got) == -1) return -1; @@ -85,8 +91,8 @@ local int gz_look(state) /* allocate read buffers and inflate memory */ if (state->size == 0) { /* allocate buffers */ - state->in = malloc(state->want); - state->out = malloc(state->want << 1); + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); if (state->in == NULL || state->out == NULL) { if (state->out != NULL) free(state->out); @@ -242,7 +248,7 @@ local int gz_fetch(state) if (gz_decomp(state) == -1) return -1; } - } while (state->x.have == 0); + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); return 0; } @@ -302,7 +308,7 @@ int ZEXPORT gzread(file, buf, len) /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids the flaw in the interface) */ if ((int)len < 0) { - gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); return -1; } @@ -329,8 +335,10 @@ int ZEXPORT gzread(file, buf, len) } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ break; + } /* need output data -- for small len or new stream load up our output buffer */ @@ -338,21 +346,21 @@ int ZEXPORT gzread(file, buf, len) /* get more output, looking for header if required */ if (gz_fetch(state) == -1) return -1; - continue; /* no progress yet -- go back to memcpy() above */ + continue; /* no progress yet -- go back to copy above */ /* the copy above assures that we will leave with space in the output buffer, allowing at least one gzungetc() to succeed */ } /* large len -- read directly into user buffer */ else if (state->how == COPY) { /* read directly */ - if (gz_load(state, buf, len, &n) == -1) + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) return -1; } /* large len -- decompress directly into user buffer */ else { /* state->how == GZIP */ strm->avail_out = len; - strm->next_out = buf; + strm->next_out = (unsigned char *)buf; if (gz_decomp(state) == -1) return -1; n = state->x.have; @@ -371,7 +379,12 @@ int ZEXPORT gzread(file, buf, len) } /* -- see zlib.h -- */ -int ZEXPORT gzgetc_(file) +#ifdef Z_PREFIX_SET +# undef z_gzgetc +#else +# undef gzgetc +#endif +int ZEXPORT gzgetc(file) gzFile file; { int ret; @@ -388,10 +401,7 @@ int ZEXPORT gzgetc_(file) (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; - /* try output buffer (no need to check for skip request) -- while - this check really isn't required since the gzgetc() macro has - already determined that x.have is zero, we leave it in for - completeness. */ + /* try output buffer (no need to check for skip request) */ if (state->x.have) { state->x.have--; state->x.pos++; @@ -403,6 +413,12 @@ int ZEXPORT gzgetc_(file) return ret < 1 ? -1 : buf[0]; } +int ZEXPORT gzgetc_(file) +gzFile file; +{ + return gzgetc(file); +} + /* -- see zlib.h -- */ int ZEXPORT gzungetc(c, file) int c; @@ -437,12 +453,13 @@ int ZEXPORT gzungetc(c, file) state->x.next = state->out + (state->size << 1) - 1; state->x.next[0] = c; state->x.pos--; + state->past = 0; return c; } /* if no room, give up (must have already done a gzungetc()) */ if (state->x.have == (state->size << 1)) { - gz_error(state, Z_BUF_ERROR, "out of room to push characters"); + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); return -1; } @@ -458,6 +475,7 @@ int ZEXPORT gzungetc(c, file) state->x.next--; state->x.next[0] = c; state->x.pos--; + state->past = 0; return c; } @@ -499,14 +517,13 @@ char * ZEXPORT gzgets(file, buf, len) if (state->x.have == 0 && gz_fetch(state) == -1) return NULL; /* error */ if (state->x.have == 0) { /* end of file */ - if (buf == str) /* got bupkus */ - return NULL; - break; /* got something -- return it */ + state->past = 1; /* read past end */ + break; /* return what we have */ } /* look for end-of-line in current output buffer */ n = state->x.have > left ? left : state->x.have; - eol = memchr(state->x.next, '\n', n); + eol = (unsigned char *)memchr(state->x.next, '\n', n); if (eol != NULL) n = (unsigned)(eol - state->x.next) + 1; @@ -519,7 +536,9 @@ char * ZEXPORT gzgets(file, buf, len) buf += n; } while (left && eol == NULL); - /* found end-of-line or out of space -- terminate string and return it */ + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; buf[0] = 0; return str; } @@ -535,16 +554,12 @@ int ZEXPORT gzdirect(file) return 0; state = (gz_statep)file; - /* check that we're reading */ - if (state->mode != GZ_READ) - return 0; - /* if the state is not known, but we can find out, then do so (this is mainly for right after a gzopen() or gzdopen()) */ - if (state->how == LOOK && state->x.have == 0) + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) (void)gz_look(state); - /* return 1 if reading direct, 0 if decompressing a gzip stream */ + /* return 1 if transparent, 0 if processing a gzip stream */ return state->direct; } @@ -552,7 +567,7 @@ int ZEXPORT gzdirect(file) int ZEXPORT gzclose_r(file) gzFile file; { - int ret; + int ret, err; gz_statep state; /* get internal structure */ @@ -570,9 +585,10 @@ int ZEXPORT gzclose_r(file) free(state->out); free(state->in); } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; gz_error(state, Z_OK, NULL); free(state->path); ret = close(state->fd); free(state); - return ret ? Z_ERRNO : Z_OK; + return ret ? Z_ERRNO : err; }