int ctf_uncompress (char *dest, int *destLen, char *source, int sourceLen) { z_stream stream; int err; memset(&stream, 0, sizeof stream); stream.next_in = source; stream.avail_in = sourceLen; /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; err = zlib_inflateInit(&stream); if (err != Z_OK) return err; err = zlib_inflate(&stream, Z_FINISH); last_err = stream.msg; if (err != Z_STREAM_END) { zlib_inflateEnd(&stream); if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) return Z_DATA_ERROR; return err; } *destLen = stream.total_out; err = zlib_inflateEnd(&stream); return err; }
void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen) { z_stream strm; int ret; down(&inflate_sem); strm.workspace = inflate_workspace; if (Z_OK != zlib_inflateInit(&strm)) { printk(KERN_WARNING "inflateInit failed\n"); up(&inflate_sem); return; } strm.next_in = data_in; strm.avail_in = srclen; strm.total_in = 0; strm.next_out = cpage_out; strm.avail_out = destlen; strm.total_out = 0; while((ret = zlib_inflate(&strm, Z_FINISH)) == Z_OK) ; if (ret != Z_STREAM_END) { printk(KERN_NOTICE "inflate returned %d\n", ret); } zlib_inflateEnd(&strm); up(&inflate_sem); }
/* Returns length of decompressed data. */ int cramfs_uncompress_block_gzip(void *dst, int dstlen, void *src, int srclen) { int err; stream.next_in = src; stream.avail_in = srclen; stream.next_out = dst; stream.avail_out = dstlen; err = zlib_inflateReset(&stream); if (err != Z_OK) { printk("zlib_inflateReset error %d\n", err); zlib_inflateEnd(&stream); zlib_inflateInit(&stream); } err = zlib_inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) goto err; return stream.total_out; err: printk("Error %d while decompressing!\n", err); printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen); return 0; }
void png_uncompress_exit(void) { if (!--initialized) { zlib_inflateEnd(&png_stream); vfree(png_stream.workspace); } }
int logfs_uncompress(void *in, void *out, size_t inlen, size_t outlen) { int err, ret; ret = -EIO; mutex_lock(&compr_mutex); err = zlib_inflateInit(&stream); if (err != Z_OK) goto error; stream.next_in = in; stream.avail_in = inlen; stream.total_in = 0; stream.next_out = out; stream.avail_out = outlen; stream.total_out = 0; err = zlib_inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) goto error; err = zlib_inflateEnd(&stream); if (err != Z_OK) goto error; ret = 0; error: mutex_unlock(&compr_mutex); return ret; }
/* Derived from logfs_uncompress */ static int pstore_decompress(void *in, void *out, size_t inlen, size_t outlen) { int err, ret; ret = -EIO; err = zlib_inflateInit2(&stream, WINDOW_BITS); if (err != Z_OK) goto error; stream.next_in = in; stream.avail_in = inlen; stream.total_in = 0; stream.next_out = out; stream.avail_out = outlen; stream.total_out = 0; err = zlib_inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) goto error; err = zlib_inflateEnd(&stream); if (err != Z_OK) goto error; ret = stream.total_out; error: return ret; }
void cramfs_uncompress_exit(void) { if (!--initialized) { zlib_inflateEnd(&stream); vfree(stream.workspace); } }
void sqlzma_fin(struct sqlzma_un *un) { int i; for (i = 0; i < SQUN_LAST; i++) if (un->un_a[i].buf && un->un_a[i].buf != un->un_prob) kfree(un->un_a[i].buf); BUG_ON(zlib_inflateEnd(&un->un_stream) != Z_OK); }
int cramfs_uncompress_exit_gzip(void) { if (!--gzip_initialized) { zlib_inflateEnd(&stream); vfree(stream.workspace); } return 0; }
static void zlib_decomp_exit(struct zlib_ctx *ctx) { struct z_stream_s *stream = &ctx->decomp_stream; if (stream->workspace) { zlib_inflateEnd(stream); vfree(stream->workspace); stream->workspace = NULL; } }
/** * z_decomp_free - Free the memory used by a decompressor. * @arg: pointer to private space for the decompressor. */ static void z_decomp_free(void *arg) { struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; if (state) { zlib_inflateEnd(&state->strm); kfree(state->strm.workspace); kfree(state); } }
/* * Decompresses the source buffer into the destination buffer. sourceLen is * the byte length of the source buffer. Upon entry, destLen is the total * size of the destination buffer, which must be large enough to hold the * entire uncompressed data. (The size of the uncompressed data must have * been saved previously by the compressor and transmitted to the decompressor * by some mechanism outside the scope of this compression library.) * Upon exit, destLen is the actual size of the compressed buffer. * This function can be used to decompress a whole file at once if the * input file is mmap'ed. * * uncompress returns Z_OK if success, Z_MEM_ERROR if there was not * enough memory, Z_BUF_ERROR if there was not enough room in the output * buffer, or Z_DATA_ERROR if the input data was corrupted. */ int z_uncompress(void *dest, size_t *destLen, const void *source, size_t sourceLen) { z_stream stream; int err; stream.next_in = (Byte *)source; stream.avail_in = (uInt)sourceLen; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((size_t)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.workspace = zlib_workspace_alloc(KM_SLEEP); if (!stream.workspace) return Z_MEM_ERROR; err = zlib_inflateInit(&stream); if (err != Z_OK) { zlib_workspace_free(stream.workspace); return err; } err = zlib_inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { zlib_inflateEnd(&stream); zlib_workspace_free(stream.workspace); if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) return Z_DATA_ERROR; return err; } *destLen = stream.total_out; err = zlib_inflateEnd(&stream); zlib_workspace_free(stream.workspace); return err; }
int gunzip_finish(struct gunzip_state *state, void *dst, int dstlen) { int len; len = gunzip_partial(state, dst, dstlen); if (state->s.workspace) { zlib_inflateEnd(&state->s); } return len; }
void sqlzma_fin(struct sqlzma_un *un) { int i; for (i = 0; i < SQUN_LAST; i++) if (un->un_a[i].buf && un->un_a[i].buf != un->un_prob) kfree(un->un_a[i].buf); #if defined(CONFIG_MIPS_BRCM) /* The FS is compressed with LZMA for BRCM: do not use zlib */ #else BUG_ON(zlib_inflateEnd(&un->un_stream) != Z_OK); #endif }
static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) { z_stream s; int r, i, flags; /* skip header */ i = 10; flags = src[3]; if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { printf("bad gzipped data\n\r"); exit(); } if ((flags & EXTRA_FIELD) != 0) i = 12 + src[10] + (src[11] << 8); if ((flags & ORIG_NAME) != 0) while (src[i++] != 0) ; if ((flags & COMMENT) != 0) while (src[i++] != 0) ; if ((flags & HEAD_CRC) != 0) i += 2; if (i >= *lenp) { printf("gunzip: ran out of data in header\n\r"); exit(); } if (zlib_inflate_workspacesize() > sizeof(scratch)) { printf("gunzip needs more mem\n"); exit(); } memset(&s, 0, sizeof(s)); s.workspace = scratch; r = zlib_inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { printf("inflateInit2 returned %d\n\r", r); exit(); } s.next_in = src + i; s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; r = zlib_inflate(&s, Z_FULL_FLUSH); if (r != Z_OK && r != Z_STREAM_END) { printf("inflate returned %d msg: %s\n\r", r, s.msg); exit(); } *lenp = s.next_out - (unsigned char *) dst; zlib_inflateEnd(&s); }
/** * z_decomp_free - Free the memory used by a decompressor. * @arg: pointer to private space for the decompressor. */ static void z_decomp_free(void *arg) { struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; if (state) { zlib_inflateEnd(&state->strm); /* LGE_CHANGE_S [LS855:[email protected]] 2011-07-11, */ #if 0 /* Delete Warning Log - OMAPS00243976 */ kfree(state->strm.workspace); #else vfree(state->strm.workspace); #endif kfree(state); } }
void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) { z_stream s; int r, i, flags; /* skip header */ i = 10; flags = src[3]; if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { puts("bad gzipped data\n"); exit(); } if ((flags & EXTRA_FIELD) != 0) i = 12 + src[10] + (src[11] << 8); if ((flags & ORIG_NAME) != 0) while (src[i++] != 0) ; if ((flags & COMMENT) != 0) while (src[i++] != 0) ; if ((flags & HEAD_CRC) != 0) i += 2; if (i >= *lenp) { puts("gunzip: ran out of data in header\n"); exit(); } /* Initialize ourself. */ s.workspace = zalloc(zlib_inflate_workspacesize()); r = zlib_inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { puts("zlib_inflateInit2 returned "); puthex(r); puts("\n"); exit(); } s.next_in = src + i; s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; r = zlib_inflate(&s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { puts("inflate returned "); puthex(r); puts("\n"); exit(); } *lenp = s.next_out - (unsigned char *) dst; zlib_inflateEnd(&s); }
void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) { z_stream s; int r, i, flags; i = 10; flags = src[3]; if (src[2] != DEFLATED || (flags & RESERVED) != 0) { exit(); } if ((flags & EXTRA_FIELD) != 0) i = 12 + src[10] + (src[11] << 8); if ((flags & ORIG_NAME) != 0) while (src[i++] != 0) ; if ((flags & COMMENT) != 0) while (src[i++] != 0) ; if ((flags & HEAD_CRC) != 0) i += 2; if (i >= *lenp) { exit(); } s.workspace = zalloc(zlib_inflate_workspacesize()); r = zlib_inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { exit(); } s.next_in = src + i; s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; r = zlib_inflate(&s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { exit(); } *lenp = s.next_out - (unsigned char *) dst; zlib_inflateEnd(&s); }
/* _VMKLNX_CODECHECK_: zlib_inflate_blob */ int zlib_inflate_blob(void *gunzip_buf, unsigned int sz, const void *buf, unsigned int len) { const u8 *zbuf = buf; struct z_stream_s *strm; int rc; #if defined(__VMKLNX__) VMK_ASSERT(vmk_PreemptionIsEnabled() == VMK_FALSE); #endif rc = -ENOMEM; strm = kmalloc(sizeof(*strm), GFP_KERNEL); if (strm == NULL) goto gunzip_nomem1; strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); if (strm->workspace == NULL) goto gunzip_nomem2; /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename) * expected to be stripped from input */ strm->next_in = zbuf; strm->avail_in = len; strm->next_out = gunzip_buf; strm->avail_out = sz; rc = zlib_inflateInit2(strm, -MAX_WBITS); if (rc == Z_OK) { rc = zlib_inflate(strm, Z_FINISH); /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ if (rc == Z_STREAM_END) rc = sz - strm->avail_out; else rc = -EINVAL; zlib_inflateEnd(strm); } else rc = -EINVAL; kfree(strm->workspace); gunzip_nomem2: kfree(strm); gunzip_nomem1: return rc; /* returns Z_OK (0) if successful */ }
/* Utility function: initialize zlib, unpack binary blob, clean up zlib, * return len or negative error code. */ int zlib_inflate_blob(void *gunzip_buf, unsigned int sz, const void *buf, unsigned int len) { const u8 *zbuf = buf; struct z_stream_s *strm; int rc; rc = -ENOMEM; strm = MALLOC(sizeof(*strm)); if (strm == NULL) goto gunzip_nomem1; strm->workspace = MALLOC(zlib_inflate_workspacesize()); if (strm->workspace == NULL) goto gunzip_nomem2; /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename) * expected to be stripped from input */ strm->next_in = zbuf; strm->avail_in = len; strm->next_out = gunzip_buf; strm->avail_out = sz; rc = zlib_inflateInit2(strm, -MAX_WBITS); if (rc == Z_OK) { rc = zlib_inflate(strm, Z_FINISH); /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ if (rc == Z_STREAM_END) rc = sz - strm->avail_out; else rc = -EINVAL; zlib_inflateEnd(strm); } else rc = -EINVAL; FREE(strm->workspace); gunzip_nomem2: FREE(strm); gunzip_nomem1: return rc; /* returns Z_OK (0) if successful */ }
static guchar *fb_gunzip(const guchar *gzip_data, ssize_t *len_ptr) { gsize gzip_data_len = *len_ptr; z_stream zstr; int gzip_err = 0; guchar *output_data; gulong gzip_len = G_MAXUINT16; g_return_val_if_fail(zlib_inflate != NULL, NULL); output_data = g_new0(guchar, gzip_len); zstr.next_in = gzip_data; zstr.avail_in = gzip_data_len; zstr.zalloc = Z_NULL; zstr.zfree = Z_NULL; zstr.opaque = Z_NULL; int flags = gzip_data[3]; int offset = 4; /* if (flags & 0x04) offset += *tmp[] */ zstr.next_in += offset; zstr.avail_in -= offset; zlib_inflateInit2_(&zstr, -MAX_WBITS, ZLIB_VERSION, sizeof(z_stream)); zstr.next_out = output_data; zstr.avail_out = gzip_len; gzip_err = zlib_inflate(&zstr, Z_FINISH); zlib_inflateEnd(&zstr); purple_debug_info("facebook", "gzip len: %ld, len: %ld\n", gzip_len, gzip_data_len); purple_debug_info("facebook", "gzip flags: %d\n", flags); purple_debug_info("facebook", "gzip error: %d\n", gzip_err); *len_ptr = gzip_len; return output_data; }
/* * Read data of @inode from @block_start to @block_end and uncompress * to one zisofs block. Store the data in the @pages array with @pcount * entries. Start storing at offset @poffset of the first page. */ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start, loff_t block_end, int pcount, struct page **pages, unsigned poffset, int *errp) { unsigned int zisofs_block_shift = ISOFS_I(inode)->i_format_parm[1]; unsigned int bufsize = ISOFS_BUFFER_SIZE(inode); unsigned int bufshift = ISOFS_BUFFER_BITS(inode); unsigned int bufmask = bufsize - 1; int i, block_size = block_end - block_start; z_stream stream = { .total_out = 0, .avail_in = 0, .avail_out = 0, }; int zerr; int needblocks = (block_size + (block_start & bufmask) + bufmask) >> bufshift; int haveblocks; blkcnt_t blocknum; struct buffer_head *bhs[needblocks + 1]; int curbh, curpage; if (block_size > deflateBound(1UL << zisofs_block_shift)) { *errp = -EIO; return 0; } /* Empty block? */ if (block_size == 0) { for ( i = 0 ; i < pcount ; i++ ) { if (!pages[i]) continue; memset(page_address(pages[i]), 0, PAGE_SIZE); flush_dcache_page(pages[i]); SetPageUptodate(pages[i]); } return ((loff_t)pcount) << PAGE_SHIFT; } /* Because zlib is not thread-safe, do all the I/O at the top. */ blocknum = block_start >> bufshift; memset(bhs, 0, (needblocks + 1) * sizeof(struct buffer_head *)); haveblocks = isofs_get_blocks(inode, blocknum, bhs, needblocks); ll_rw_block(REQ_OP_READ, 0, haveblocks, bhs); curbh = 0; curpage = 0; /* * First block is special since it may be fractional. We also wait for * it before grabbing the zlib mutex; odds are that the subsequent * blocks are going to come in in short order so we don't hold the zlib * mutex longer than necessary. */ if (!bhs[0]) goto b_eio; wait_on_buffer(bhs[0]); if (!buffer_uptodate(bhs[0])) { *errp = -EIO; goto b_eio; } stream.workspace = zisofs_zlib_workspace; mutex_lock(&zisofs_zlib_lock); zerr = zlib_inflateInit(&stream); if (zerr != Z_OK) { if (zerr == Z_MEM_ERROR) *errp = -ENOMEM; else *errp = -EIO; printk(KERN_DEBUG "zisofs: zisofs_inflateInit returned %d\n", zerr); goto z_eio; } while (curpage < pcount && curbh < haveblocks && zerr != Z_STREAM_END) { if (!stream.avail_out) { if (pages[curpage]) { stream.next_out = page_address(pages[curpage]) + poffset; stream.avail_out = PAGE_SIZE - poffset; poffset = 0; } else { stream.next_out = (void *)&zisofs_sink_page; stream.avail_out = PAGE_SIZE; } } if (!stream.avail_in) { wait_on_buffer(bhs[curbh]); if (!buffer_uptodate(bhs[curbh])) { *errp = -EIO; break; } stream.next_in = bhs[curbh]->b_data + (block_start & bufmask); stream.avail_in = min_t(unsigned, bufsize - (block_start & bufmask), block_size); block_size -= stream.avail_in; block_start = 0; } while (stream.avail_out && stream.avail_in) { zerr = zlib_inflate(&stream, Z_SYNC_FLUSH); if (zerr == Z_BUF_ERROR && stream.avail_in == 0) break; if (zerr == Z_STREAM_END) break; if (zerr != Z_OK) { /* EOF, error, or trying to read beyond end of input */ if (zerr == Z_MEM_ERROR) *errp = -ENOMEM; else { printk(KERN_DEBUG "zisofs: zisofs_inflate returned" " %d, inode = %lu," " page idx = %d, bh idx = %d," " avail_in = %ld," " avail_out = %ld\n", zerr, inode->i_ino, curpage, curbh, stream.avail_in, stream.avail_out); *errp = -EIO; } goto inflate_out; } } if (!stream.avail_out) { /* This page completed */ if (pages[curpage]) { flush_dcache_page(pages[curpage]); SetPageUptodate(pages[curpage]); } curpage++; } if (!stream.avail_in) curbh++; } inflate_out: zlib_inflateEnd(&stream); z_eio: mutex_unlock(&zisofs_zlib_lock); b_eio: for (i = 0; i < haveblocks; i++) brelse(bhs[i]); return stream.total_out; }
static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, struct buffer_head **bh, int b, int offset, int length, int srclength, int pages) { int zlib_err = 0, zlib_init = 0; int avail, bytes, k = 0, page = 0; z_stream *stream = msblk->stream; mutex_lock(&msblk->read_data_mutex); stream->avail_out = 0; stream->avail_in = 0; bytes = length; do { if (stream->avail_in == 0 && k < b) { avail = min(bytes, msblk->devblksize - offset); bytes -= avail; wait_on_buffer(bh[k]); if (!buffer_uptodate(bh[k])) goto release_mutex; if (avail == 0) { offset = 0; put_bh(bh[k++]); continue; } stream->next_in = bh[k]->b_data + offset; stream->avail_in = avail; offset = 0; } if (stream->avail_out == 0 && page < pages) { stream->next_out = buffer[page++]; stream->avail_out = PAGE_CACHE_SIZE; } if (!zlib_init) { zlib_err = zlib_inflateInit(stream); if (zlib_err != Z_OK) { ERROR("zlib_inflateInit returned unexpected " "result 0x%x, srclength %d\n", zlib_err, srclength); goto release_mutex; } zlib_init = 1; } zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH); if (stream->avail_in == 0 && k < b) put_bh(bh[k++]); } while (zlib_err == Z_OK); if (zlib_err != Z_STREAM_END) { ERROR("zlib_inflate error, data probably corrupt\n"); goto release_mutex; } zlib_err = zlib_inflateEnd(stream); if (zlib_err != Z_OK) { ERROR("zlib_inflate error, data probably corrupt\n"); goto release_mutex; } length = stream->total_out; mutex_unlock(&msblk->read_data_mutex); return length; release_mutex: mutex_unlock(&msblk->read_data_mutex); for (; k < b; k++) put_bh(bh[k]); return -EIO; }
static void deflate_decomp_exit(struct deflate_ctx *ctx) { zlib_inflateEnd(&ctx->decomp_stream); kfree(ctx->decomp_stream.workspace); }
static int zlib_uncompress(struct squashfs_sb_info *msblk, void *strm, struct buffer_head **bh, int b, int offset, int length, struct squashfs_page_actor *output) { int zlib_err, zlib_init = 0, k = 0; z_stream *stream = strm; stream->avail_out = PAGE_SIZE; stream->next_out = squashfs_first_page(output); stream->avail_in = 0; do { if (stream->avail_in == 0 && k < b) { int avail = min(length, msblk->devblksize - offset); length -= avail; stream->next_in = bh[k]->b_data + offset; stream->avail_in = avail; offset = 0; } if (stream->avail_out == 0) { stream->next_out = squashfs_next_page(output); if (stream->next_out != NULL) stream->avail_out = PAGE_SIZE; } if (!zlib_init) { zlib_err = zlib_inflateInit(stream); if (zlib_err != Z_OK) { squashfs_finish_page(output); goto out; } zlib_init = 1; } zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH); if (stream->avail_in == 0 && k < b) put_bh(bh[k++]); } while (zlib_err == Z_OK); squashfs_finish_page(output); if (zlib_err != Z_STREAM_END) goto out; zlib_err = zlib_inflateEnd(stream); if (zlib_err != Z_OK) goto out; if (k < b) goto out; return stream->total_out; out: for (; k < b; k++) put_bh(bh[k]); return -EIO; }
/* Included from initramfs et al code */ STATIC int INIT __gunzip(unsigned char *buf, long len, long (*fill)(void*, unsigned long), long (*flush)(void*, unsigned long), unsigned char *out_buf, long out_len, long *pos, void(*error)(char *x)) { u8 *zbuf; struct z_stream_s *strm; int rc; rc = -1; if (flush) { out_len = 0x8000; /* 32 K */ out_buf = malloc(out_len); } else { if (!out_len) out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */ } if (!out_buf) { error("Out of memory while allocating output buffer"); goto gunzip_nomem1; } if (buf) zbuf = buf; else { zbuf = malloc(GZIP_IOBUF_SIZE); len = 0; } if (!zbuf) { error("Out of memory while allocating input buffer"); goto gunzip_nomem2; } strm = malloc(sizeof(*strm)); if (strm == NULL) { error("Out of memory while allocating z_stream"); goto gunzip_nomem3; } strm->workspace = malloc(flush ? zlib_inflate_workspacesize() : sizeof(struct inflate_state)); if (strm->workspace == NULL) { error("Out of memory while allocating workspace"); goto gunzip_nomem4; } if (!fill) fill = nofill; if (len == 0) len = fill(zbuf, GZIP_IOBUF_SIZE); /* verify the gzip header */ if (len < 10 || zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) { if (pos) *pos = 0; error("Not a gzip file"); goto gunzip_5; } /* skip over gzip header (1f,8b,08... 10 bytes total + * possible asciz filename) */ strm->next_in = zbuf + 10; strm->avail_in = len - 10; /* skip over asciz filename */ if (zbuf[3] & 0x8) { do { /* * If the filename doesn't fit into the buffer, * the file is very probably corrupt. Don't try * to read more data. */ if (strm->avail_in == 0) { error("header error"); goto gunzip_5; } --strm->avail_in; } while (*strm->next_in++); } strm->next_out = out_buf; strm->avail_out = out_len; rc = zlib_inflateInit2(strm, -MAX_WBITS); if (!flush) { WS(strm)->inflate_state.wsize = 0; WS(strm)->inflate_state.window = NULL; } while (rc == Z_OK) { if (strm->avail_in == 0) { /* TODO: handle case where both pos and fill are set */ len = fill(zbuf, GZIP_IOBUF_SIZE); if (len < 0) { rc = -1; error("read error"); break; } strm->next_in = zbuf; strm->avail_in = len; } rc = zlib_inflate(strm, 0); /* Write any data generated */ if (flush && strm->next_out > out_buf) { long l = strm->next_out - out_buf; if (l != flush(out_buf, l)) { rc = -1; error("write error"); break; } strm->next_out = out_buf; strm->avail_out = out_len; } /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ if (rc == Z_STREAM_END) { rc = 0; break; } else if (rc != Z_OK) { error("uncompression error"); rc = -1; } } zlib_inflateEnd(strm); if (pos) /* add + 8 to skip over trailer */ *pos = strm->next_in - zbuf+8; gunzip_5: free(strm->workspace); gunzip_nomem4: free(strm); gunzip_nomem3: if (!buf) free(zbuf); gunzip_nomem2: if (flush) free(out_buf); gunzip_nomem1: return rc; /* returns Z_OK (0) if successful */ }