Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 4
0
Archivo: png.c Proyecto: zandar/barebox
void png_uncompress_exit(void)
{
    if (!--initialized) {
        zlib_inflateEnd(&png_stream);
        vfree(png_stream.workspace);
    }
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
/* 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;
}
Ejemplo n.º 7
0
void cramfs_uncompress_exit(void)
{
	if (!--initialized) {
		zlib_inflateEnd(&stream);
		vfree(stream.workspace);
	}
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 10
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;
	}
}
Ejemplo n.º 11
0
/**
 *	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);
	}
}
Ejemplo n.º 12
0
/*
 * 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
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
0
/**
 *	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);
	}
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 18
0
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 */
}
Ejemplo n.º 20
0
/* 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 */
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
/*
 * 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;
}
Ejemplo n.º 23
0
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;
}
Ejemplo n.º 24
0
static void deflate_decomp_exit(struct deflate_ctx *ctx)
{
    zlib_inflateEnd(&ctx->decomp_stream);
    kfree(ctx->decomp_stream.workspace);
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
/* 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 */
}