NS_CC_BEGIN

// --------------------- ZipUtils ---------------------

// memory in iPhone is precious
// Should buffer factor be 1.5 instead of 2 ?
#define BUFFER_INC_FACTOR (2)

int ZipUtils::ccInflateMemoryWithHint(unsigned char *in, unsigned int inLength, unsigned char **out, unsigned int *outLength, unsigned int outLenghtHint)
{
    /* ret value */
    int err = Z_OK;

    int bufferSize = outLenghtHint;
    *out = new unsigned char[bufferSize];

    z_stream d_stream; /* decompression stream */    
    d_stream.zalloc = (alloc_func)0;
    d_stream.zfree = (free_func)0;
    d_stream.opaque = (voidpf)0;

    d_stream.next_in  = in;
    d_stream.avail_in = inLength;
    d_stream.next_out = *out;
    d_stream.avail_out = bufferSize;

    /* window size to hold 256k */
    if( (err = inflateInit2(&d_stream, 15 + 32)) != Z_OK )
        return err;

    for (;;) 
    {
        err = inflate(&d_stream, Z_NO_FLUSH);

        if (err == Z_STREAM_END)
        {
            break;
        }

        switch (err) 
        {
        case Z_NEED_DICT:
            err = Z_DATA_ERROR;
        case Z_DATA_ERROR:
        case Z_MEM_ERROR:
            inflateEnd(&d_stream);
            return err;
        }

        // not enough memory ?
        if (err != Z_STREAM_END) 
        {
            delete [] *out;
            *out = new unsigned char[bufferSize * BUFFER_INC_FACTOR];

            /* not enough memory, ouch */
            if (! *out ) 
            {
                CCLOG("cocos2d: ZipUtils: realloc failed");
                inflateEnd(&d_stream);
                return Z_MEM_ERROR;
            }

            d_stream.next_out = *out + bufferSize;
            d_stream.avail_out = bufferSize;
            bufferSize *= BUFFER_INC_FACTOR;
        }
    }

    *outLength = bufferSize - d_stream.avail_out;
    err = inflateEnd(&d_stream);
    return err;
}
Exemplo n.º 2
0
static gchar *skypeweb_gunzip(const guchar *gzip_data, gssize *len_ptr)
{
	gsize gzip_data_len	= *len_ptr;
	z_stream zstr;
	int gzip_err = 0;
	gchar *data_buffer;
	gulong gzip_len = G_MAXUINT16;
	GString *output_string = NULL;

	data_buffer = g_new0(gchar, gzip_len);

	zstr.next_in = NULL;
	zstr.avail_in = 0;
	zstr.zalloc = Z_NULL;
	zstr.zfree = Z_NULL;
	zstr.opaque = 0;
	gzip_err = inflateInit2(&zstr, MAX_WBITS+32);
	if (gzip_err != Z_OK)
	{
		g_free(data_buffer);
		purple_debug_error("skypeweb", "no built-in gzip support in zlib\n");
		return NULL;
	}
	
	zstr.next_in = (Bytef *)gzip_data;
	zstr.avail_in = gzip_data_len;
	
	zstr.next_out = (Bytef *)data_buffer;
	zstr.avail_out = gzip_len;
	
	gzip_err = inflate(&zstr, Z_SYNC_FLUSH);

	if (gzip_err == Z_DATA_ERROR)
	{
		inflateEnd(&zstr);
		inflateInit2(&zstr, -MAX_WBITS);
		if (gzip_err != Z_OK)
		{
			g_free(data_buffer);
			purple_debug_error("skypeweb", "Cannot decode gzip header\n");
			return NULL;
		}
		zstr.next_in = (Bytef *)gzip_data;
		zstr.avail_in = gzip_data_len;
		zstr.next_out = (Bytef *)data_buffer;
		zstr.avail_out = gzip_len;
		gzip_err = inflate(&zstr, Z_SYNC_FLUSH);
	}
	output_string = g_string_new("");
	while (gzip_err == Z_OK)
	{
		//append data to buffer
		output_string = g_string_append_len(output_string, data_buffer, gzip_len - zstr.avail_out);
		//reset buffer pointer
		zstr.next_out = (Bytef *)data_buffer;
		zstr.avail_out = gzip_len;
		gzip_err = inflate(&zstr, Z_SYNC_FLUSH);
	}
	if (gzip_err == Z_STREAM_END)
	{
		output_string = g_string_append_len(output_string, data_buffer, gzip_len - zstr.avail_out);
	} else {
		purple_debug_error("skypeweb", "gzip inflate error\n");
	}
	inflateEnd(&zstr);

	g_free(data_buffer);	

	if (len_ptr)
		*len_ptr = output_string->len;

	return g_string_free(output_string, FALSE);
}
Exemplo n.º 3
0
uint64_t PackUtils::Unpack(istream& in, uint64_t size, ostream& out)
{
	uint64_t result = 0;
	int ret;
	uint64_t remaining = size;
	uint64_t have;
	z_stream strm;

	char readBuf[PackUtils::CHUNK];
	char writeBuf[PackUtils::CHUNK];

	/* allocate inflate state */
	strm.zalloc = Z_NULL;
	strm.zfree = Z_NULL;
	strm.opaque = Z_NULL;
	strm.avail_in = 0;
	strm.next_in = Z_NULL;

	ret = inflateInit(&strm);
	
	if (ret != Z_OK)
		return 0;

	/* decompress until deflate stream ends or end of file */
	do 
	{
		strm.avail_in = PackUtils::CHUNK;
		if(remaining < PackUtils::CHUNK)
		{
			strm.avail_in = (uInt)remaining;
		}
		remaining -= strm.avail_in;

		if(!in.read(readBuf, strm.avail_in))
		{
			strm.avail_in = (uInt)in.gcount();
		}

		if (in.bad()) 
		{
			(void)inflateEnd(&strm);
			return 0;
		}

		if (strm.avail_in == 0)
			break;

		strm.next_in = (Bytef*) readBuf;

		/* run inflate() on input until output buffer not full */
		do 
		{
			strm.avail_out = CHUNK;
			strm.next_out = (Bytef*) writeBuf;
			ret = inflate(&strm, Z_NO_FLUSH);
			
			switch (ret) 
			{
				case Z_NEED_DICT:
					ret = Z_DATA_ERROR;     /* and fall through */
				case Z_DATA_ERROR:
				case Z_MEM_ERROR:
					(void)inflateEnd(&strm);
					return 0;
			}

			have = CHUNK - strm.avail_out;

			result += have;
			
			out.write(writeBuf, have);

			if (out.bad()) 
			{
				(void)inflateEnd(&strm);
				return 0;
			}

		} while (strm.avail_out == 0);

		/* done when inflate() says it's done */
	} while (ret != Z_STREAM_END);

	/* clean up and return */
	(void)inflateEnd(&strm);
	return ret == Z_STREAM_END ? result : 0;
}
Exemplo n.º 4
0
static php_stream_filter_status_t php_zlib_inflate_filter(
	php_stream *stream,
	php_stream_filter *thisfilter,
	php_stream_bucket_brigade *buckets_in,
	php_stream_bucket_brigade *buckets_out,
	size_t *bytes_consumed,
	int flags
	TSRMLS_DC)
{
	php_zlib_filter_data *data;
	php_stream_bucket *bucket;
	size_t consumed = 0, original_out, original_in;
	int status;
	php_stream_filter_status_t exit_status = PSFS_FEED_ME;
	z_stream *streamp;

	if (!thisfilter || !thisfilter->abstract) {
		/* Should never happen */
		return PSFS_ERR_FATAL;
	}

	data = (php_zlib_filter_data *)(thisfilter->abstract);
	streamp = &(data->strm);
	original_in = data->strm.total_in;
	original_out = data->strm.total_out;

	while (buckets_in->head) {
		size_t bin = 0, desired;

		bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC);
		while (bin < bucket->buflen) {
			desired = bucket->buflen - bin;
			if (desired > data->inbuf_len) {
				desired = data->inbuf_len;
			}
			memcpy(data->strm.next_in, bucket->buf + bin, desired);
			data->strm.avail_in = desired;

			status = inflate(&(data->strm), flags & PSFS_FLAG_FLUSH_CLOSE ? Z_FINISH : Z_SYNC_FLUSH);
			if (status != Z_OK && status != Z_STREAM_END) {
				/* Something bad happened */
				php_stream_bucket_delref(bucket TSRMLS_CC);
				return PSFS_ERR_FATAL;
			}
			desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */
			data->strm.next_in = data->inbuf;
			data->strm.avail_in = 0;
			consumed += desired;
			bin += desired;

			if (!desired) {
				flags |= PSFS_FLAG_FLUSH_CLOSE;
				break;
			}

			if (data->strm.avail_out < data->outbuf_len) {
				php_stream_bucket *out_bucket;
				size_t bucketlen = data->outbuf_len - data->strm.avail_out;
				out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC);
				php_stream_bucket_append(buckets_out, out_bucket TSRMLS_CC);
				data->strm.avail_out = data->outbuf_len;
				data->strm.next_out = data->outbuf;
				exit_status = PSFS_PASS_ON;
			}
		}
		php_stream_bucket_delref(bucket TSRMLS_CC);
	}

	if (flags & PSFS_FLAG_FLUSH_CLOSE) {
		/* Spit it out! */
		status = Z_OK;
		while (status == Z_OK) {
			status = inflate(&(data->strm), Z_FINISH);
			if (data->strm.avail_out < data->outbuf_len) {
				size_t bucketlen = data->outbuf_len - data->strm.avail_out;

				bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC);
				php_stream_bucket_append(buckets_out, bucket TSRMLS_CC);
				data->strm.avail_out = data->outbuf_len;
				data->strm.next_out = data->outbuf;
				exit_status = PSFS_PASS_ON;
			}
		}
	}

	if (bytes_consumed) {
		*bytes_consumed = consumed;
	}

	return exit_status;
}
Exemplo n.º 5
0
/*
  Read bytes from the current file.
  buf contain buffer where data must be copied
  len the size of buf.

  return the number of byte copied if somes bytes are copied
  return 0 if the end of file was reached
  return <0 with error code if there is an error
    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
extern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, uint32_t len)
{
	int32_t err=UNZ_OK;
	uInt iRead = 0;
	unz_s* s;
	file_in_zip_read_info_s* pfile_in_zip_read_info;
	if (file==NULL)
		return UNZ_PARAMERROR;
	s=(unz_s*)file;
    pfile_in_zip_read_info=s->pfile_in_zip_read;

	if (pfile_in_zip_read_info==NULL)
		return UNZ_PARAMERROR;


	if ((pfile_in_zip_read_info->read_buffer == NULL))
		return UNZ_END_OF_LIST_OF_FILE;
	if (len==0)
		return 0;

	pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;

	pfile_in_zip_read_info->stream.avail_out = (uInt)len;

	if (len>pfile_in_zip_read_info->rest_read_uncompressed)
		pfile_in_zip_read_info->stream.avail_out =
		  (uInt)pfile_in_zip_read_info->rest_read_uncompressed;

	while (pfile_in_zip_read_info->stream.avail_out>0)
	{
		if ((pfile_in_zip_read_info->stream.avail_in==0) &&
	    (pfile_in_zip_read_info->rest_read_compressed>0))
		{
			uInt uReadThis = UNZ_BUFSIZE;
			if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
				uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
			if (uReadThis == 0)
				return UNZ_EOF;
			if (zfile_fseek(pfile_in_zip_read_info->file,
		      pfile_in_zip_read_info->pos_in_zipfile +
			 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
				return UNZ_ERRNO;
			if (zfile_fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
			 pfile_in_zip_read_info->file)!=1)
				return UNZ_ERRNO;
			pfile_in_zip_read_info->pos_in_zipfile += uReadThis;

			pfile_in_zip_read_info->rest_read_compressed-=uReadThis;

			pfile_in_zip_read_info->stream.next_in =
		(Bytef*)pfile_in_zip_read_info->read_buffer;
			pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
		}

		if (pfile_in_zip_read_info->compression_method==0)
		{
			uInt uDoCopy,i ;
			if (pfile_in_zip_read_info->stream.avail_out <
			    pfile_in_zip_read_info->stream.avail_in)
				uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
			else
				uDoCopy = pfile_in_zip_read_info->stream.avail_in ;

			for (i=0;i<uDoCopy;i++)
				*(pfile_in_zip_read_info->stream.next_out+i) =
			*(pfile_in_zip_read_info->stream.next_in+i);

			pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
								pfile_in_zip_read_info->stream.next_out,
								uDoCopy);
			pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
			pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
			pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
			pfile_in_zip_read_info->stream.next_out += uDoCopy;
			pfile_in_zip_read_info->stream.next_in += uDoCopy;
	    pfile_in_zip_read_info->stream.total_out += uDoCopy;
			iRead += uDoCopy;
		}
		else
		{
			uLong uTotalOutBefore,uTotalOutAfter;
			const Bytef *bufBefore;
			uLong uOutThis;
			int32_t flush=Z_SYNC_FLUSH;

			uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
			bufBefore = pfile_in_zip_read_info->stream.next_out;

			/*
			if ((pfile_in_zip_read_info->rest_read_uncompressed ==
				 pfile_in_zip_read_info->stream.avail_out) &&
				(pfile_in_zip_read_info->rest_read_compressed == 0))
				flush = Z_FINISH;
			*/
			err=inflate(&pfile_in_zip_read_info->stream,flush);

			uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
			uOutThis = uTotalOutAfter-uTotalOutBefore;

			pfile_in_zip_read_info->crc32 =
			crc32(pfile_in_zip_read_info->crc32,bufBefore,
			(uInt)(uOutThis));

			pfile_in_zip_read_info->rest_read_uncompressed -=
		uOutThis;

			iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);

			if (err==Z_STREAM_END)
				return (iRead==0) ? UNZ_EOF : iRead;
			if (err!=Z_OK)
				break;
		}
	}

	if (err==Z_OK)
		return iRead;
	return err;
}
Exemplo n.º 6
0
int doInflate(char *smallBuffer, char *bigBuffer)
{
	unsigned char			*inBuffer = NULL;
	unsigned char			*outBuffer = NULL;
	char					*smallBufferP;
	char					*bigBufferP;
	int						inBufferSize;
	int						outBufferSize;
	int						bytesToGo = cmpBufferSize;
	int						bytesCopied = 0;
	int						bytesToProcess;
	int						err;
	int						done = 0;
	z_stream				decompStream;

	inBufferSize = INBUFFERSIZE;
	outBufferSize = INBUFFERSIZE;

	if ((inBuffer = (unsigned char *)malloc(inBufferSize)) == NULL) {
		fprintf(stderr, "Error allocating memory for input buffer\n");
		goto memerr;
	}
	if ((outBuffer = (unsigned char *)malloc(outBufferSize)) == NULL) {
		fprintf(stderr, "Error allocating memory for output buffer\n");
		goto memerr;
	}

	smallBufferP = smallBuffer + 1; /* move past magic number */
	bigBufferP = bigBuffer;

	decompStream.zalloc = (alloc_func)0;
	decompStream.zfree = (free_func)0;
	decompStream.opaque = (voidpf)0;

	err = inflateInit(&decompStream);
	CHECK_ERR(err, "inflateInit");

	bytesToProcess = (bytesToGo > inBufferSize) ? inBufferSize : bytesToGo;
	memcpy(inBuffer, smallBufferP, bytesToProcess);
	bytesToGo -= bytesToProcess;
	smallBufferP += bytesToProcess;

	decompStream.next_in  = inBuffer;
	decompStream.next_out  = outBuffer;

	while (!done)
	{
		decompStream.avail_in = bytesToProcess;
		decompStream.avail_out = outBufferSize;

		while(decompStream.avail_in)
		{
			err = inflate(&decompStream, Z_NO_FLUSH);
			if (err == Z_STREAM_END)
				break;
			CHECK_ERR(err, "inflate");

			memcpy(bigBufferP, outBuffer, decompStream.next_out - outBuffer);
			bigBufferP += decompStream.next_out - outBuffer;
			bytesCopied += decompStream.next_out - outBuffer;

			decompStream.next_out = outBuffer;
			decompStream.avail_out = outBufferSize;
		}

		bytesToProcess = (bytesToGo > inBufferSize) ? inBufferSize : bytesToGo;
		if (bytesToProcess == 0)
			done = 1;
		else
		{
			memcpy(inBuffer, smallBufferP, bytesToProcess);
			bytesToGo -= bytesToProcess;
			smallBufferP += bytesToProcess;

			decompStream.next_in  = inBuffer;
			decompStream.next_out = outBuffer;
		}
	}

	err = inflateEnd(&decompStream);
	CHECK_ERR(err, "inflateEnd");

	free(inBuffer);
	free(outBuffer);

	appBufferSize = bytesCopied;

	return(ERR_OK);

memerr:
	if (inBuffer != NULL)
		free(inBuffer);
	if (outBuffer != NULL)
		free(outBuffer);
	return(Z_MEM_ERROR);
}
Exemplo n.º 7
0
bool eZ80AccessorSZX::SetState(xIo::eStreamMemory& is)
{
	ZXSTHEADER header;
	if(is.Read(&header, sizeof(header)) != sizeof(header))
		return false;
	if(header.dwMagic != FOURCC('Z', 'X', 'S', 'T'))
		return false;
	bool model48k = false;
	switch(header.chMachineId)
	{
	case ZXSTMID_16K:
	case ZXSTMID_48K:
	case ZXSTMID_NTSC48K:
		model48k = true;
		break;
	case ZXSTMID_128K:
	case ZXSTMID_PENTAGON128:
		break;
	default:
		return false;
	}
	SetupDevices(model48k);
	ZXSTBLOCK block;
	while(is.Read(&block, sizeof(block)) == sizeof(block))
	{
		switch(block.dwId)
		{
		case FOURCC('Z', '8', '0', 'R'):
			{
				ZXSTZ80REGS regs;
				if(!ReadBlock(is, &regs, block))
					return false;
				af = SwapWord(regs.AF);
				bc = SwapWord(regs.BC);
				de = SwapWord(regs.DE);
				hl = SwapWord(regs.HL);
				alt.af = SwapWord(regs.AF1);
				alt.bc = SwapWord(regs.BC1);
				alt.de = SwapWord(regs.DE1);
				alt.hl = SwapWord(regs.HL1);

				ix = SwapWord(regs.IX);
				iy = SwapWord(regs.IY);
				sp = SwapWord(regs.SP);
				pc = SwapWord(regs.PC);
				i = regs.I;
				r_low = regs.R;
				r_hi = regs.R & 0x80;
				im = regs.IM;
				iff1 = regs.IFF1;
				iff2 = regs.IFF2;
				t = Dword((const byte*)&regs.dwCyclesStart) % frame_tacts;
				if(regs.wMemPtr)
					memptr = SwapWord(regs.wMemPtr);
			}
			break;
		case FOURCC('S', 'P', 'C', 'R'):
			{
				ZXSTSPECREGS regs;
				if(!ReadBlock(is, &regs, block))
					return false;
				devices->IoWrite(0xfe, (regs.chFe&0x18) | regs.chBorder, t);
				devices->IoWrite(0x7ffd, model48k ? 0x30 : regs.ch7ffd, t);
				if(model48k)
					devices->Get<eMemory>()->SetRomPage(eMemory::P_ROM_48);
				else
					devices->Get<eMemory>()->SetRomPage((regs.ch7ffd & 0x10) ? eMemory::P_ROM_128_0 : eMemory::P_ROM_128_1);
			}
			break;
		case FOURCC('R', 'A', 'M', 'P'):
			{
				ZXSTRAMPAGE ram_page;
				if(!ReadBlock(is, &ram_page, block, sizeof(ZXSTRAMPAGE) - sizeof(ZXSTBLOCK) - 1))
					return false;
				byte* buf = new byte[eMemory::PAGE_SIZE];
				bool ok = false;
				if(SwapWord(ram_page.wFlags)&ZXSTRF_COMPRESSED)
				{
#ifdef USE_ZIP
					size_t size = ram_page.blk.dwSize - (sizeof(ZXSTRAMPAGE) - sizeof(ZXSTBLOCK) - 1);
					byte* buf_compr = new byte[size];
					ok = is.Read(buf_compr, size) == size;
					if(ok)
					{
						z_stream zs;
						memset(&zs, 0, sizeof(zs));
						zs.next_in = buf_compr;
						zs.avail_in = size;
						zs.next_out = buf;
						zs.avail_out = eMemory::PAGE_SIZE;
						ok = inflateInit2(&zs, 15) == Z_OK;
						if(ok)
							ok = inflate(&zs, Z_NO_FLUSH) == Z_STREAM_END;
						inflateEnd(&zs);
					}
					SAFE_DELETE_ARRAY(buf_compr);
#endif//USE_ZIP
				}
				else
				{
					size_t size = ram_page.blk.dwSize - (sizeof(ZXSTRAMPAGE) - sizeof(ZXSTBLOCK) - 1);
					ok = size == eMemory::PAGE_SIZE;
					if(ok)
					{
						ok = is.Read(buf, size) == size;
					}
				}
				if(ok && ram_page.chPageNo <= 7)
				{
					memcpy(memory->Get(eMemory::P_RAM0 + ram_page.chPageNo), buf, eMemory::PAGE_SIZE);
				}
				SAFE_DELETE(buf);
				if(!ok)
					return false;
			}
			break;
		case FOURCC('A', 'Y', '\0', '\0'):
			{
				ZXSTAYBLOCK ay_state;
				if(!ReadBlock(is, &ay_state, block))
					return false;
				devices->Get<eAY>()->SetRegs(ay_state.chAyRegs);
				devices->Get<eAY>()->Select(ay_state.chCurrentRegister);
			}
			break;
		default:
			if(is.Seek(block.dwSize, xIo::eStreamMemory::S_CUR) != 0)
				return false;
		}
		if(is.Pos() == is.Size())
			return true;
	}
	return false;
}
Exemplo n.º 8
0
/** Given zero or more zlib-compressed or gzip-compressed strings of
 * total length
 * <b>in_len</b> bytes at <b>in</b>, uncompress them into a newly allocated
 * buffer, using the method described in <b>method</b>.  Store the uncompressed
 * string in *<b>out</b>, and its length in *<b>out_len</b>.  Return 0 on
 * success, -1 on failure.
 *
 * If <b>complete_only</b> is true, we consider a truncated input as a
 * failure; otherwise we decompress as much as we can.  Warn about truncated
 * or corrupt inputs at <b>protocol_warn_level</b>.
 */
int
tor_gzip_uncompress(char **out, size_t *out_len,
                    const char *in, size_t in_len,
                    compress_method_t method,
                    int complete_only,
                    int protocol_warn_level)
{
  struct z_stream_s *stream = NULL;
  size_t out_size, old_size;
  off_t offset;
  int r;

  tor_assert(out);
  tor_assert(out_len);
  tor_assert(in);
  tor_assert(in_len < UINT_MAX);

  if (method == GZIP_METHOD && !is_gzip_supported()) {
    /* Old zlib version don't support gzip in inflateInit2 */
    log_warn(LD_BUG, "Gzip not supported with zlib %s", ZLIB_VERSION);
    return -1;
  }

  *out = NULL;

  stream = tor_malloc_zero(sizeof(struct z_stream_s));
  stream->zalloc = Z_NULL;
  stream->zfree = Z_NULL;
  stream->opaque = NULL;
  stream->next_in = (unsigned char*) in;
  stream->avail_in = (unsigned int)in_len;

  if (inflateInit2(stream,
                   method_bits(method)) != Z_OK) {
    log_warn(LD_GENERAL, "Error from inflateInit2: %s",
             stream->msg?stream->msg:"<no message>");
    goto err;
  }

  out_size = in_len * 2;  /* guess 50% compression. */
  if (out_size < 1024) out_size = 1024;
  if (out_size > UINT_MAX)
    goto err;

  *out = tor_malloc(out_size);
  stream->next_out = (unsigned char*)*out;
  stream->avail_out = (unsigned int)out_size;

  while (1) {
    switch (inflate(stream, complete_only ? Z_FINISH : Z_SYNC_FLUSH))
      {
      case Z_STREAM_END:
        if (stream->avail_in == 0)
          goto done;
        /* There may be more compressed data here. */
        if ((r = inflateEnd(stream)) != Z_OK) {
          log_warn(LD_BUG, "Error freeing gzip structures");
          goto err;
        }
        if (inflateInit2(stream, method_bits(method)) != Z_OK) {
          log_warn(LD_GENERAL, "Error from second inflateInit2: %s",
                   stream->msg?stream->msg:"<no message>");
          goto err;
        }
        break;
      case Z_OK:
        if (!complete_only && stream->avail_in == 0)
          goto done;
        /* In case zlib doesn't work as I think.... */
        if (stream->avail_out >= stream->avail_in+16)
          break;
      case Z_BUF_ERROR:
        if (stream->avail_out > 0) {
          log_fn(protocol_warn_level, LD_PROTOCOL,
                 "possible truncated or corrupt zlib data");
          goto err;
        }
        offset = stream->next_out - (unsigned char*)*out;
        old_size = out_size;
        out_size *= 2;
        if (out_size < old_size) {
          log_warn(LD_GENERAL, "Size overflow in compression.");
          goto err;
        }
        *out = tor_realloc(*out, out_size);
        stream->next_out = (unsigned char*)(*out + offset);
        if (out_size - offset > UINT_MAX) {
          log_warn(LD_BUG,  "Ran over unsigned int limit of zlib while "
                   "uncompressing.");
          goto err;
        }
        stream->avail_out = (unsigned int)(out_size - offset);
        break;
      default:
        log_warn(LD_GENERAL, "Gzip decompression returned an error: %s",
                 stream->msg ? stream->msg : "<no message>");
        goto err;
      }
  }
 done:
  *out_len = stream->next_out - (unsigned char*)*out;
  r = inflateEnd(stream);
  tor_free(stream);
  if (r != Z_OK) {
    log_warn(LD_BUG, "Error freeing gzip structures");
    goto err;
  }

  /* NUL-terminate output. */
  if (out_size == *out_len)
    *out = tor_realloc(*out, out_size + 1);
  (*out)[*out_len] = '\0';

  return 0;
 err:
  if (stream) {
    inflateEnd(stream);
    tor_free(stream);
  }
  if (*out) {
    tor_free(*out);
  }
  return -1;
}
Exemplo n.º 9
0
bool inflateMemory(char *in, unsigned inLength,
                   char *&out, unsigned &outLength)
{
    int bufferSize = 256 * 1024;
    int ret;
    z_stream strm;

    out = (char *)malloc(bufferSize);

    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;
    strm.next_in = (Bytef *)in;
    strm.avail_in = inLength;
    strm.next_out = (Bytef *)out;
    strm.avail_out = bufferSize;

    ret = inflateInit2(&strm, 15 + 32);

    if (ret != Z_OK)
    {
        logZlibError(ret);
        free(out);
        return false;
    }

    do
    {
        ret = inflate(&strm, Z_SYNC_FLUSH);

        switch (ret) {
            case Z_NEED_DICT:
            case Z_STREAM_ERROR:
                ret = Z_DATA_ERROR;
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                inflateEnd(&strm);
                logZlibError(ret);
                free(out);
                return false;
        }

        if (ret != Z_STREAM_END)
        {
            out = (char *)realloc(out, bufferSize * 2);

            if (!out)
            {
                inflateEnd(&strm);
                logZlibError(Z_MEM_ERROR);
                free(out);
                return false;
            }

            strm.next_out = (Bytef *)(out + bufferSize);
            strm.avail_out = bufferSize;
            bufferSize *= 2;
        }
    }
    while (ret != Z_STREAM_END);

    if (strm.avail_in != 0)
    {
        logZlibError(Z_DATA_ERROR);
        free(out);
        return false;
    }

    outLength = bufferSize - strm.avail_out;
    inflateEnd(&strm);
    return true;
}
Exemplo n.º 10
0
 virtual std::streambuf::int_type underflow()
 {
     if (this->gptr() == this->egptr())
     {
         // pointers for free region in output buffer
         char * out_buff_free_start = out_buff;
         do
         {
             // read more input if none available
             if (in_buff_start == in_buff_end)
             {
                 // empty input buffer: refill from the start
                 in_buff_start = in_buff;
                 std::streamsize sz = sbuf_p->sgetn(in_buff, buff_size);
                 in_buff_end = in_buff + sz;
                 if (in_buff_end == in_buff_start) break; // end of input
             }
             // auto detect if the stream contains text or deflate data
             if (auto_detect && ! auto_detect_run)
             {
                 auto_detect_run = true;
                 unsigned char b0 = *reinterpret_cast< unsigned char * >(in_buff_start);
                 unsigned char b1 = *reinterpret_cast< unsigned char * >(in_buff_start + 1);
                 // Ref:
                 // http://en.wikipedia.org/wiki/Gzip
                 // http://stackoverflow.com/questions/9050260/what-does-a-zlib-header-look-like
                 is_text = ! (in_buff_start + 2 <= in_buff_end
                              && ((b0 == 0x1F && b1 == 0x8B)         // gzip header
                                  || (b0 == 0x78 && (b1 == 0x01      // zlib header
                                                     || b1 == 0x9C
                                                     || b1 == 0xDA))));
             }
             if (is_text)
             {
                 // simply swap in_buff and out_buff, and adjust pointers
                 assert(in_buff_start == in_buff);
                 std::swap(in_buff, out_buff);
                 out_buff_free_start = in_buff_end;
                 in_buff_start = in_buff;
                 in_buff_end = in_buff;
             }
             else
             {
                 // run inflate() on input
                 if (! zstrm_p) zstrm_p = new detail::z_stream_wrapper(true);
                 zstrm_p->next_in = reinterpret_cast< decltype(zstrm_p->next_in) >(in_buff_start);
                 zstrm_p->avail_in = in_buff_end - in_buff_start;
                 zstrm_p->next_out = reinterpret_cast< decltype(zstrm_p->next_out) >(out_buff_free_start);
                 zstrm_p->avail_out = (out_buff + buff_size) - out_buff_free_start;
                 int ret = inflate(zstrm_p, Z_NO_FLUSH);
                 // process return code
                 if (ret != Z_OK && ret != Z_STREAM_END) throw Exception(zstrm_p, ret);
                 // update in&out pointers following inflate()
                 in_buff_start = reinterpret_cast< decltype(in_buff_start) >(zstrm_p->next_in);
                 in_buff_end = in_buff_start + zstrm_p->avail_in;
                 out_buff_free_start = reinterpret_cast< decltype(out_buff_free_start) >(zstrm_p->next_out);
                 assert(out_buff_free_start + zstrm_p->avail_out == out_buff + buff_size);
                 // if stream ended, deallocate inflator
                 if (ret == Z_STREAM_END)
                 {
                     delete zstrm_p;
                     zstrm_p = nullptr;
                 }
             }
         } while (out_buff_free_start == out_buff);
         // 2 exit conditions:
         // - end of input: there might or might not be output available
         // - out_buff_free_start != out_buff: output available
         this->setg(out_buff, out_buff, out_buff_free_start);
     }
     return this->gptr() == this->egptr()
         ? traits_type::eof()
         : traits_type::to_int_type(*this->gptr());
 }
Exemplo n.º 11
0
static ssize_t i_stream_zlib_read(struct istream_private *stream)
{
	struct zlib_istream *zstream = (struct zlib_istream *)stream;
	const unsigned char *data;
	uoff_t high_offset;
	size_t size;
	int ret;

	high_offset = stream->istream.v_offset + (stream->pos - stream->skip);
	if (zstream->eof_offset == high_offset) {
		i_assert(zstream->high_pos == 0 ||
			 zstream->high_pos == stream->pos);
		if (!zstream->trailer_read) {
			do {
				ret = i_stream_zlib_read_trailer(zstream);
			} while (ret == 0 && stream->istream.blocking);
			if (ret <= 0)
				return ret;
		}
		if (!zstream->gz || i_stream_is_eof(stream->parent)) {
			stream->istream.eof = TRUE;
			return -1;
		}
		/* gzip file with concatenated content */
		zstream->eof_offset = (uoff_t)-1;
		zstream->stream_size = (uoff_t)-1;
		zstream->header_read = FALSE;
		zstream->trailer_read = FALSE;
		zstream->crc32 = 0;

		(void)inflateEnd(&zstream->zs);
		i_stream_zlib_init(zstream);
	}

	if (!zstream->header_read) {
		do {
			ret = i_stream_zlib_read_header(stream);
		} while (ret == 0 && stream->istream.blocking);
		if (ret <= 0)
			return ret;
		zstream->header_read = TRUE;
		zstream->prev_size = 0;
	}

	if (stream->pos < zstream->high_pos) {
		/* we're here because we seeked back within the read buffer. */
		ret = zstream->high_pos - stream->pos;
		stream->pos = zstream->high_pos;
		zstream->high_pos = 0;
		if (zstream->trailer_read) {
			high_offset = stream->istream.v_offset +
				(stream->pos - stream->skip);
			i_assert(zstream->eof_offset == high_offset);
			stream->istream.eof = TRUE;
		}
		return ret;
	}
	zstream->high_pos = 0;

	if (stream->pos + CHUNK_SIZE > stream->buffer_size) {
		/* try to keep at least CHUNK_SIZE available */
		if (!zstream->marked && stream->skip > 0) {
			/* don't try to keep anything cached if we don't
			   have a seek mark. */
			i_stream_compress(stream);
		}
		if (stream->max_buffer_size == 0 ||
		    stream->buffer_size < stream->max_buffer_size)
			i_stream_grow_buffer(stream, CHUNK_SIZE);

		if (stream->pos == stream->buffer_size) {
			if (stream->skip > 0) {
				/* lose our buffer cache */
				i_stream_compress(stream);
			}

			if (stream->pos == stream->buffer_size)
				return -2; /* buffer full */
		}
	}

	if (zstream->zs.avail_in == 0) {
		/* need to read more data. try to read a full CHUNK_SIZE */
		i_stream_skip(stream->parent, zstream->prev_size);
		if (i_stream_read_data(stream->parent, &data, &size,
				       CHUNK_SIZE-1) == -1 && size == 0) {
			if (stream->parent->stream_errno != 0) {
				stream->istream.stream_errno =
					stream->parent->stream_errno;
			} else {
				i_assert(stream->parent->eof);
				if (zstream->log_errors) {
					zlib_read_error(zstream,
							"unexpected EOF");
				}
				stream->istream.stream_errno = EPIPE;
			}
			return -1;
		}
		zstream->prev_size = size;
		if (size == 0) {
			/* no more input */
			i_assert(!stream->istream.blocking);
			return 0;
		}

		zstream->zs.next_in = (void *)data;
		zstream->zs.avail_in = size;
	}

	size = stream->buffer_size - stream->pos;
	zstream->zs.next_out = stream->w_buffer + stream->pos;
	zstream->zs.avail_out = size;
	ret = inflate(&zstream->zs, Z_SYNC_FLUSH);

	size -= zstream->zs.avail_out;
	zstream->crc32 = crc32_data_more(zstream->crc32,
					 stream->w_buffer + stream->pos, size);
	stream->pos += size;

	switch (ret) {
	case Z_OK:
		break;
	case Z_NEED_DICT:
		if (zstream->log_errors)
			zlib_read_error(zstream, "can't read file without dict");
		stream->istream.stream_errno = EINVAL;
		return -1;
	case Z_DATA_ERROR:
		if (zstream->log_errors)
			zlib_read_error(zstream, "corrupted data");
		stream->istream.stream_errno = EINVAL;
		return -1;
	case Z_MEM_ERROR:
		i_fatal_status(FATAL_OUTOFMEM, "zlib.read(%s): Out of memory",
			       i_stream_get_name(&stream->istream));
	case Z_STREAM_END:
		zstream->eof_offset = stream->istream.v_offset +
			(stream->pos - stream->skip);
		zstream->stream_size = zstream->eof_offset;
		i_stream_skip(stream->parent,
			      zstream->prev_size - zstream->zs.avail_in);
		zstream->zs.avail_in = 0;
		zstream->prev_size = 0;

		if (!zstream->trailer_read) {
			/* try to read and verify the trailer, we might not
			   be called again. */
			if (i_stream_zlib_read_trailer(zstream) < 0)
				return -1;
		}
		break;
	default:
		i_fatal("inflate() failed with %d", ret);
	}
	if (size == 0) {
		/* read more input */
		return i_stream_zlib_read(stream);
	}
	return size;
}
Exemplo n.º 12
0
/* 使用 zlib 来压缩解压缩文件 */
char * zcodecom(int mode, char * inbuf, int inbuf_len, int * resultbuf_len)
{
    //php_printf("<!-- lcrypt7: zcodecom:%s -->\r\n", inbuf);
    int count, status;
    char * resultbuf;
    int total_count = 0;

    z.zalloc = Z_NULL;
    z.zfree = Z_NULL;
    z.opaque = Z_NULL;

    z.next_in = Z_NULL;
    z.avail_in = 0;
    if (mode == 0) {
        /* 压缩 初始化 */
        deflateInit(&z, 1);
    } else {
        /* 解压缩 初始化 */
        inflateInit(&z);
    }

    z.next_out = (Bytef *) outbuf;
    z.avail_out = OUTBUFSIZ;
    z.next_in = (Bytef *) inbuf;
    z.avail_in = inbuf_len;

    resultbuf = malloc(OUTBUFSIZ);

    while (1) {
        if (mode == 0) {
            /* 压缩 */
            status = deflate(&z, Z_FINISH);
        } else {
            /* 解压缩 */
            status = inflate(&z, Z_NO_FLUSH);
        }
        if (status == Z_STREAM_END) {
            break;
        }
        if (status != Z_OK) {
            if (mode == 0) {
                deflateEnd(&z);
            } else {
                inflateEnd(&z);
            }
            *resultbuf_len = 0;
            return (resultbuf);
        }
        /* 内存空间不够? */
        if (z.avail_out == 0) {
            resultbuf = realloc(resultbuf, total_count + OUTBUFSIZ);
            memcpy(resultbuf + total_count, outbuf, OUTBUFSIZ);
            total_count += OUTBUFSIZ;
            z.next_out = (Bytef *) outbuf;
            z.avail_out = OUTBUFSIZ;
        }
    }
    if ((count = OUTBUFSIZ - z.avail_out) != 0) {
        resultbuf = realloc(resultbuf, total_count + OUTBUFSIZ);
        memcpy(resultbuf + total_count, outbuf, count);
        total_count += count;
    }
    if (mode == 0) {
        /* 压缩完成 */
        deflateEnd(&z);
    } else {
        /* 解压缩完成 */
        inflateEnd(&z);
    }
    *resultbuf_len = total_count;
    return(resultbuf);
}
Exemplo n.º 13
0
static char *
_xbps_uncompress_plist_data(char *xml, size_t len)
{
	z_stream strm;
	unsigned char *out;
	char *uncomp_xml = NULL;
	size_t have;
	ssize_t totalsize = 0;
	int rv = 0;

	assert(xml != NULL);

	/* Decompress the mmap'ed buffer with zlib */
	strm.zalloc = Z_NULL;
	strm.zfree = Z_NULL;
	strm.opaque = Z_NULL;
	strm.avail_in = 0;
	strm.next_in = Z_NULL;

	/* 15+16 to use gzip method */
	if (inflateInit2(&strm, 15+16) != Z_OK)
		return NULL;

	strm.avail_in = len;
	strm.next_in = (unsigned char *)xml;

	/* Output buffer (uncompressed) */
	if ((uncomp_xml = malloc(_READ_CHUNK)) == NULL) {
		(void)inflateEnd(&strm);
		return NULL;
	}

	/* temp output buffer for inflate */
	if ((out = malloc(_READ_CHUNK)) == NULL) {
		(void)inflateEnd(&strm);
		free(uncomp_xml);
		return NULL;
	}

	/* Inflate the input buffer and copy into 'uncomp_xml' */
	do {
		strm.avail_out = _READ_CHUNK;
		strm.next_out = out;
		rv = inflate(&strm, Z_NO_FLUSH);
		switch (rv) {
		case Z_DATA_ERROR:
			/*
			 * Wrong compressed data or uncompressed, try
			 * normal method as last resort.
			 */
			(void)inflateEnd(&strm);
			free(uncomp_xml);
			free(out);
			errno = EAGAIN;
			return NULL;
		case Z_STREAM_ERROR:
		case Z_NEED_DICT:
		case Z_MEM_ERROR:
		case Z_BUF_ERROR:
		case Z_VERSION_ERROR:
			(void)inflateEnd(&strm);
			free(uncomp_xml);
			free(out);
			return NULL;
		}
		have = _READ_CHUNK - strm.avail_out;
		totalsize += have;
		uncomp_xml = realloc(uncomp_xml, totalsize);
		memcpy(uncomp_xml + totalsize - have, out, have);
	} while (strm.avail_out == 0);

	/* we are done */
	(void)inflateEnd(&strm);
	free(out);

	return uncomp_xml;
}
Exemplo n.º 14
0
u_int32_t
deflate_global(u_int8_t *data, u_int32_t size, int decomp, u_int8_t **out)
{
    /* decomp indicates whether we compress (0) or decompress (1) */

    z_stream zbuf;
    u_int8_t *output;
    u_int32_t count, result;
    int error, i = 0, j;
    struct deflate_buf buf[ZBUF];

    bzero(&zbuf, sizeof(z_stream));
    for (j = 0; j < ZBUF; j++)
        buf[j].flag = 0;

    zbuf.next_in = data;	/* data that is going to be processed */
    zbuf.zalloc = z_alloc;
    zbuf.zfree = z_free;
    zbuf.opaque = Z_NULL;
    zbuf.avail_in = size;	/* Total length of data to be processed */

    if (!decomp) {
        buf[i].out = kmalloc((u_long) size, M_CRYPTO_DATA, M_WAITOK);
        if (buf[i].out == NULL)
            goto bad;
        buf[i].size = size;
        buf[i].flag = 1;
        i++;
    } else {
        /*
         * Choose a buffer with 4x the size of the input buffer
         * for the size of the output buffer in the case of
         * decompression. If it's not sufficient, it will need to be
         * updated while the decompression is going on
         */

        buf[i].out = kmalloc((u_long) (size * 4),
                             M_CRYPTO_DATA, M_WAITOK);
        if (buf[i].out == NULL)
            goto bad;
        buf[i].size = size * 4;
        buf[i].flag = 1;
        i++;
    }

    zbuf.next_out = buf[0].out;
    zbuf.avail_out = buf[0].size;

    error = decomp ? inflateInit2(&zbuf, window_inflate) :
            deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD,
                         window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY);

    if (error != Z_OK)
        goto bad;
    for (;;) {
        error = decomp ? inflate(&zbuf, Z_PARTIAL_FLUSH) :
                deflate(&zbuf, Z_PARTIAL_FLUSH);
        if (error != Z_OK && error != Z_STREAM_END)
            goto bad;
        else if (zbuf.avail_in == 0 && zbuf.avail_out != 0)
            goto end;
        else if (zbuf.avail_out == 0 && i < (ZBUF - 1)) {
            /* we need more output space, allocate size */
            buf[i].out = kmalloc((u_long) size,
                                 M_CRYPTO_DATA, M_WAITOK);
            if (buf[i].out == NULL)
                goto bad;
            zbuf.next_out = buf[i].out;
            buf[i].size = size;
            buf[i].flag = 1;
            zbuf.avail_out = buf[i].size;
            i++;
        } else
            goto bad;
    }

end:
    result = count = zbuf.total_out;

    *out = kmalloc((u_long) result, M_CRYPTO_DATA, M_WAITOK);
    if (*out == NULL)
        goto bad;
    if (decomp)
        inflateEnd(&zbuf);
    else
        deflateEnd(&zbuf);
    output = *out;
    for (j = 0; buf[j].flag != 0; j++) {
        if (count > buf[j].size) {
            bcopy(buf[j].out, *out, buf[j].size);
            *out += buf[j].size;
            kfree(buf[j].out, M_CRYPTO_DATA);
            count -= buf[j].size;
        } else {
            /* it should be the last buffer */
            bcopy(buf[j].out, *out, count);
            *out += count;
            kfree(buf[j].out, M_CRYPTO_DATA);
            count = 0;
        }
    }
    *out = output;
    return result;

bad:
    *out = NULL;
    for (j = 0; buf[j].flag != 0; j++)
        kfree(buf[j].out, M_CRYPTO_DATA);
    if (decomp)
        inflateEnd(&zbuf);
    else
        deflateEnd(&zbuf);
    return 0;
}
Exemplo n.º 15
0
  bool PreprocessPBF::ReadPrimitiveBlock(Progress& progress,
                                         FILE* file,
                                         const PBF::BlockHeader& blockHeader,
                                         PBF::PrimitiveBlock& primitiveBlock)
  {
    PBF::Blob               blob;
    google::protobuf::int32 length=blockHeader.datasize();

    if (length==0 || length>MAX_BLOB_SIZE) {
      progress.Error("Blob size invalid!");
      return false;
    }

    AssureBlockSize(length);

    if (fread(buffer,sizeof(char),length,file)!=(size_t)length) {
      progress.Error("Cannot read blob!");
      return false;
    }

    if (!blob.ParseFromArray(buffer,length)) {
      progress.Error("Cannot parse blob!");
      return false;
    }

    if (blob.has_raw()) {
      length=(uint32_t)blob.raw().length();
      AssureBlockSize(length);
      memcpy(buffer,blob.raw().data(),(size_t)length);
    }
    else if (blob.has_zlib_data()) {
#if defined(HAVE_LIB_ZLIB)
      length=blob.raw_size();
      AssureBlockSize(length);

      z_stream compressedStream;

      compressedStream.next_in=(Bytef*)const_cast<char*>(blob.zlib_data().data());
      compressedStream.avail_in=(uint32_t)blob.zlib_data().size();
      compressedStream.next_out=(Bytef*)buffer;
      compressedStream.avail_out=(uInt)length;
      compressedStream.zalloc=Z_NULL;
      compressedStream.zfree=Z_NULL;
      compressedStream.opaque=Z_NULL;

      if (inflateInit( &compressedStream)!=Z_OK) {
        progress.Error("Cannot decode zlib compressed blob data!");
        return false;
      }

      if (inflate(&compressedStream,Z_FINISH)!=Z_STREAM_END) {
        progress.Error("Cannot decode zlib compressed blob data!");
        return false;
      }

      if (inflateEnd(&compressedStream)!=Z_OK) {
        progress.Error("Cannot decode zlib compressed blob data!");
        return false;
      }
#else
      progress.Error("Data is zlib encoded but zlib support is not enabled!");
      return false;
#endif
    }
    else if (blob.has_bzip2_data()) {
      progress.Error("Data is bzip2 encoded but bzip2 support is not enabled!");
      return false;
    }
    else if (blob.has_lzma_data()) {
      progress.Error("Data is lzma encoded but lzma support is not enabled!");
      return false;
    }

    if (!primitiveBlock.ParseFromArray(buffer,length)) {
      progress.Error("Cannot parse primitive block!");
      return false;
    }

    return true;
  }
Exemplo n.º 16
0
/* Zlib-specific Decompression function. */
static inline int SnortDecompressZlib(decompress_state_t *state, uint8_t *input, uint32_t input_len,
                               uint8_t *output, uint32_t output_bufsize, uint32_t *output_len)
{
    z_streamp zlib_stream = (z_streamp) state->lib_info;
    int zlib_ret;
    int snort_ret = SNORT_DECOMPRESS_OK;

    if (zlib_stream == NULL)
        return SNORT_DECOMPRESS_BAD_ARGUMENT; // Uninitialized state object.

    /* The call to inflateInit() requires some data to be provided.
       That's why the call isn't done in SnortDecompressInit(). */
    if (state->flags & SNORT_ZLIB_INIT_NEEDED)
    {
        if (input == NULL)
            return SNORT_DECOMPRESS_BAD_ARGUMENT;

        zlib_stream->next_in = input;
        zlib_stream->avail_in = input_len;

        /* Deflate can be either raw or with a zlib header so we'll
         * just use the normal inflateInit and if inflate fails, add
         * a dummy zlib header.  Just like Chrome and Firefox do.
         * gzip decompression requires adding 16 to zlibs MAX_WBITS 
         */
        if (state->type == COMPRESSION_TYPE_DEFLATE)
            zlib_ret = inflateInit(zlib_stream);
        else
            zlib_ret = inflateInit2(zlib_stream, GZIP_ZLIB_WBITS);
        state->lib_return = zlib_ret;

        state->flags &= ~SNORT_ZLIB_INIT_NEEDED;
    }
    /* If input is NULL, just continue decompressing from the last spot.
       This is how a caller would handle truncated output. */
    else if (input)
    {
        zlib_stream->next_in = input;
        zlib_stream->avail_in = input_len;
    }

    zlib_stream->next_out = output;
    zlib_stream->avail_out = output_bufsize;

    while (zlib_stream->avail_in > 0 && zlib_stream->avail_out > 0)
    {
        zlib_ret = inflate(zlib_stream, Z_SYNC_FLUSH);

        if ((zlib_ret == Z_DATA_ERROR)
                && (state->type == COMPRESSION_TYPE_DEFLATE)
                && (!state->deflate_initialized))
        {
            /* Might not have zlib header - add one */
            static char zlib_header[2] = { 0x78, 0x01 };

            inflateReset(zlib_stream);
            zlib_stream->next_in = (Bytef *)zlib_header;
            zlib_stream->avail_in = sizeof(zlib_header);

            zlib_ret = inflate(zlib_stream, Z_SYNC_FLUSH);
            state->deflate_initialized = true;

            if (input)
            {
                zlib_stream->next_in = input;
                zlib_stream->avail_in = input_len;
            }
        }

        state->lib_return = zlib_ret;

        if (zlib_ret == Z_STREAM_END)
            break; // Not an error, just hit the end of compressed data.

        if (zlib_ret != Z_OK)
        {
            snort_ret = SNORT_DECOMPRESS_BAD_DATA;
            break;
        }
    }

    if ((zlib_stream->avail_in > 0 && zlib_stream->avail_out == 0) &&
        (snort_ret != SNORT_DECOMPRESS_BAD_DATA))
    {
        snort_ret = SNORT_DECOMPRESS_OUTPUT_TRUNC;
    }

    *output_len = output_bufsize - zlib_stream->avail_out;

    return snort_ret;
}
Exemplo n.º 17
0
void /* PRIVATE */
png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
{
   if (png_ptr->buffer_size && png_ptr->current_text_left)
   {
      png_size_t text_size;

      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
         text_size = png_ptr->buffer_size;
      else
         text_size = png_ptr->current_text_left;
      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
      png_ptr->current_text_left -= text_size;
      png_ptr->current_text_ptr += text_size;
   }
   if (!(png_ptr->current_text_left))
   {
      png_textp text_ptr;
      png_charp text;
      png_charp key;
      int ret;
      png_size_t text_size, key_size;

      if (png_ptr->buffer_size < 4)
      {
         png_push_save_buffer(png_ptr);
         return;
      }

      png_push_crc_finish(png_ptr);

      key = png_ptr->current_text;

      for (text = key; *text; text++)
         /* empty loop */ ;

      /* zTXt can't have zero text */
      if (text == key + png_ptr->current_text_size)
      {
         png_ptr->current_text = NULL;
         png_free(png_ptr, key);
         return;
      }

      text++;

      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
      {
         png_ptr->current_text = NULL;
         png_free(png_ptr, key);
         return;
      }

      text++;

      png_ptr->zstream.next_in = (png_bytep )text;
      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
         (text - key));
      png_ptr->zstream.next_out = png_ptr->zbuf;
      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;

      key_size = text - key;
      text_size = 0;
      text = NULL;
      ret = Z_STREAM_END;

      while (png_ptr->zstream.avail_in)
      {
         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
         if (ret != Z_OK && ret != Z_STREAM_END)
         {
            inflateReset(&png_ptr->zstream);
            png_ptr->zstream.avail_in = 0;
            png_ptr->current_text = NULL;
            png_free(png_ptr, key);
            png_free(png_ptr, text);
            return;
         }
         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
         {
            if (text == NULL)
            {
               text = (png_charp)png_malloc(png_ptr,
                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
                     + key_size + 1));
               png_memcpy(text + key_size, png_ptr->zbuf,
                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
               png_memcpy(text, key, key_size);
               text_size = key_size + png_ptr->zbuf_size -
                  png_ptr->zstream.avail_out;
               *(text + text_size) = '\0';
            }
            else
            {
               png_charp tmp;

               tmp = text;
               text = (png_charp)png_malloc(png_ptr, text_size +
                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
                   + 1));
               png_memcpy(text, tmp, text_size);
               png_free(png_ptr, tmp);
               png_memcpy(text + text_size, png_ptr->zbuf,
                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
               *(text + text_size) = '\0';
            }
            if (ret != Z_STREAM_END)
            {
               png_ptr->zstream.next_out = png_ptr->zbuf;
               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
            }
         }
         else
         {
            break;
         }

         if (ret == Z_STREAM_END)
            break;
      }

      inflateReset(&png_ptr->zstream);
      png_ptr->zstream.avail_in = 0;

      if (ret != Z_STREAM_END)
      {
         png_ptr->current_text = NULL;
         png_free(png_ptr, key);
         png_free(png_ptr, text);
         return;
      }

      png_ptr->current_text = NULL;
      png_free(png_ptr, key);
      key = text;
      text += key_size;

      text_ptr = (png_textp)png_malloc(png_ptr,
          (png_uint_32)png_sizeof(png_text));
      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
      text_ptr->key = key;
#ifdef PNG_iTXt_SUPPORTED
      text_ptr->lang = NULL;
      text_ptr->lang_key = NULL;
#endif
      text_ptr->text = text;

      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);

      png_free(png_ptr, key);
      png_free(png_ptr, text_ptr);

      if (ret)
        png_warning(png_ptr, "Insufficient memory to store text chunk.");
   }
}
Exemplo n.º 18
0
dword C_file_read_zip::ReadCache(){

   curr = base;

   if(file_info.method==file_info.METHOD_STORE){
                           //raw read, no compression
      dword sz = Min(int(CACHE_SIZE), int(GetFileSize()-curr_pos));
      if(arch_file)
         arch_file->Read(base, sz);
      else{
#ifdef SYMBIAN_OPTIM
         TPtr8 desc(base, sz);
         file.Read(desc);
#else
         ck.Read(base, sz);
#endif
      }
      top = base + sz;
      return sz;
   }
                           //read next data from cache
   d_stream.next_out = base;
   d_stream.avail_out = Min(int(CACHE_SIZE), int(file_info.sz_uncompressed-d_stream.total_out));

   dword num_read = d_stream.total_out;
   while(d_stream.avail_out){
      int flush_flag = 0;
      if(!d_stream.avail_in){
         dword sz = Min(int(sizeof(d_buf)), int(file_info.sz_compressed-d_stream.total_in));
         if(sz){
            if(arch_file)
               arch_file->Read(d_buf, sz);
            else{
#ifdef SYMBIAN_OPTIM
               TPtr8 desc(d_buf, sz);
               file.Read(desc);
#else
               ck.Read(d_buf, sz);
#endif
            }
            d_stream.next_in = d_buf;
            d_stream.avail_in = sz;
         }else
            flush_flag = Z_SYNC_FLUSH;
      }
      int err = inflate(&d_stream, flush_flag);
      if(err == Z_STREAM_END)
         break;
      if(err != Z_OK){
         switch(err){
         case Z_MEM_ERROR: assert(0); break; //ZIP file decompression failed (memory error).
         case Z_BUF_ERROR: assert(0); break; //ZIP file decompression failed (buffer error).
         case Z_DATA_ERROR: assert(0); break;//ZIP file decompression failed (data error).
         default: assert(0);  //ZIP file decompression failed (unknown error).
         }
         return 0;
      }
   }
   num_read = d_stream.total_out - num_read;
   top = base + num_read;
   return num_read;
}
Exemplo n.º 19
0
/*
 * FUNCTION: Uncompresses data in a buffer
 * ARGUMENTS:
 *     OutputBuffer = Pointer to buffer to place uncompressed data
 *     InputBuffer  = Pointer to buffer with data to be uncompressed
 *     InputLength  = Length of input buffer before, and amount consumed after
 *                    Negative to indicate that this is not the start of a new block
 *     OutputLength = Length of output buffer before, amount filled after
 *                    Negative to indicate that this is not the end of the block
 */
ULONG
MSZipCodecUncompress(PVOID OutputBuffer,
                     PVOID InputBuffer,
                     PLONG InputLength,
                     PLONG OutputLength)
{
    USHORT Magic;
    INT Status;

    DPRINT("MSZipCodecUncompress(OutputBuffer = %x, InputBuffer = %x, "
           "InputLength = %d, OutputLength = %d)\n", OutputBuffer,
           InputBuffer, *InputLength, *OutputLength);
    if (*InputLength > 0)
    {
        Magic = *(PUSHORT)InputBuffer;

        if (Magic != MSZIP_MAGIC)
        {
            DPRINT("Bad MSZIP block header magic (0x%X)\n", Magic);
            return CS_BADSTREAM;
        }

        ZStream.next_in = (PUCHAR)InputBuffer + 2;
        ZStream.avail_in = *InputLength - 2;
        ZStream.next_out = (PUCHAR)OutputBuffer;
        ZStream.avail_out = abs(*OutputLength);

        /* WindowBits is passed < 0 to tell that there is no zlib header.
         * Note that in this case inflate *requires* an extra "dummy" byte
         * after the compressed stream in order to complete decompression and
         * return Z_STREAM_END.
         */
        Status = inflateInit2(&ZStream, -MAX_WBITS);
        if (Status != Z_OK)
        {
            DPRINT("inflateInit2() returned (%d)\n", Status);
            return CS_BADSTREAM;
        }
        ZStream.total_in = 2;
    }
    else
    {
        ZStream.avail_in = -*InputLength;
        ZStream.next_in = (PUCHAR)InputBuffer;
        ZStream.next_out = (PUCHAR)OutputBuffer;
        ZStream.avail_out = abs(*OutputLength);
        ZStream.total_in = 0;
    }

    ZStream.total_out = 0;
    Status = inflate(&ZStream, Z_SYNC_FLUSH);
    if (Status != Z_OK && Status != Z_STREAM_END)
    {
        DPRINT("inflate() returned (%d) (%s)\n", Status, ZStream.msg);
        if (Status == Z_MEM_ERROR)
            return CS_NOMEMORY;
        return CS_BADSTREAM;
    }

    if (*OutputLength > 0)
    {
        Status = inflateEnd(&ZStream);
        if (Status != Z_OK)
        {
            DPRINT("inflateEnd() returned (%d)\n", Status);
            return CS_BADSTREAM;
        }
    }

    *OutputLength = ZStream.total_out;
    *InputLength = ZStream.total_in;

    return CS_SUCCESS;
}
Exemplo n.º 20
0
QByteArray qt_inflateGZipDataFrom(QIODevice *device)
{
    if (!device)
        return QByteArray();

    if (!device->isOpen())
        device->open(QIODevice::ReadOnly);

    Q_ASSERT(device->isOpen() && device->isReadable());

    static const int CHUNK_SIZE = 4096;
    int zlibResult = Z_OK;

    QByteArray source;
    QByteArray destination;

    // Initialize zlib stream struct
    z_stream zlibStream;
    zlibStream.next_in = Z_NULL;
    zlibStream.avail_in = 0;
    zlibStream.avail_out = 0;
    zlibStream.zalloc = Z_NULL;
    zlibStream.zfree = Z_NULL;
    zlibStream.opaque = Z_NULL;

    // Adding 16 to the window size gives us gzip decoding
    if (inflateInit2(&zlibStream, MAX_WBITS + 16) != Z_OK) {
        qWarning("Cannot initialize zlib, because: %s",
                (zlibStream.msg != NULL ? zlibStream.msg : "Unknown error"));
        return QByteArray();
    }

    bool stillMoreWorkToDo = true;
    while (stillMoreWorkToDo) {

        if (!zlibStream.avail_in) {
            source = device->read(CHUNK_SIZE);

            if (source.isEmpty())
                break;

            zlibStream.avail_in = source.size();
            zlibStream.next_in = reinterpret_cast<Bytef*>(source.data());
        }

        do {
            // Prepare the destination buffer
            int oldSize = destination.size();
            destination.resize(oldSize + CHUNK_SIZE);
            zlibStream.next_out = reinterpret_cast<Bytef*>(
                    destination.data() + oldSize - zlibStream.avail_out);
            zlibStream.avail_out += CHUNK_SIZE;

            zlibResult = inflate(&zlibStream, Z_NO_FLUSH);
            switch (zlibResult) {
                case Z_NEED_DICT:
                case Z_DATA_ERROR:
                case Z_STREAM_ERROR:
                case Z_MEM_ERROR: {
                    inflateEnd(&zlibStream);
                    qWarning("Error while inflating gzip file: %s",
                            (zlibStream.msg != NULL ? zlibStream.msg : "Unknown error"));
                    destination.chop(zlibStream.avail_out);
                    return destination;
                }
            }

        // If the output buffer still has more room after calling inflate
        // it means we have to provide more data, so exit the loop here
        } while (!zlibStream.avail_out);

        if (zlibResult == Z_STREAM_END) {
            // Make sure there are no more members to process before exiting
            if (!(zlibStream.avail_in && inflateReset(&zlibStream) == Z_OK))
                stillMoreWorkToDo = false;
        }
    }

    // Chop off trailing space in the buffer
    destination.chop(zlibStream.avail_out);

    inflateEnd(&zlibStream);
    return destination;
}
Exemplo n.º 21
0
void PNGAPI
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
{
#ifdef PNG_USE_LOCAL_ARRAYS
    PNG_CONST PNG_IDAT;
    PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
                                          0xff
                                         };
    PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
#endif
    int ret;
    if(png_ptr == NULL) return;
    png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
               png_ptr->row_number, png_ptr->pass);
    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
        png_read_start_row(png_ptr);
    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
    {

#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
        if (png_ptr->transformations & PNG_INVERT_MONO)
            png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
        if (png_ptr->transformations & PNG_FILLER)
            png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
        if (png_ptr->transformations & PNG_PACKSWAP)
            png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
        if (png_ptr->transformations & PNG_PACK)
            png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
        if (png_ptr->transformations & PNG_SHIFT)
            png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
        if (png_ptr->transformations & PNG_BGR)
            png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
        if (png_ptr->transformations & PNG_SWAP_BYTES)
            png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
#endif
    }

#if defined(PNG_READ_INTERLACING_SUPPORTED)

    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
    {
        switch (png_ptr->pass)
        {
        case 0:
            if (png_ptr->row_number & 0x07)
            {
                if (dsp_row != NULL)
                    png_combine_row(png_ptr, dsp_row,
                                    png_pass_dsp_mask[png_ptr->pass]);
                png_read_finish_row(png_ptr);
                return;
            }
            break;
        case 1:
            if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
            {
                if (dsp_row != NULL)
                    png_combine_row(png_ptr, dsp_row,
                                    png_pass_dsp_mask[png_ptr->pass]);
                png_read_finish_row(png_ptr);
                return;
            }
            break;
        case 2:
            if ((png_ptr->row_number & 0x07) != 4)
            {
                if (dsp_row != NULL && (png_ptr->row_number & 4))
                    png_combine_row(png_ptr, dsp_row,
                                    png_pass_dsp_mask[png_ptr->pass]);
                png_read_finish_row(png_ptr);
                return;
            }
            break;
        case 3:
            if ((png_ptr->row_number & 3) || png_ptr->width < 3)
            {
                if (dsp_row != NULL)
                    png_combine_row(png_ptr, dsp_row,
                                    png_pass_dsp_mask[png_ptr->pass]);
                png_read_finish_row(png_ptr);
                return;
            }
            break;
        case 4:
            if ((png_ptr->row_number & 3) != 2)
            {
                if (dsp_row != NULL && (png_ptr->row_number & 2))
                    png_combine_row(png_ptr, dsp_row,
                                    png_pass_dsp_mask[png_ptr->pass]);
                png_read_finish_row(png_ptr);
                return;
            }
            break;
        case 5:
            if ((png_ptr->row_number & 1) || png_ptr->width < 2)
            {
                if (dsp_row != NULL)
                    png_combine_row(png_ptr, dsp_row,
                                    png_pass_dsp_mask[png_ptr->pass]);
                png_read_finish_row(png_ptr);
                return;
            }
            break;
        case 6:
            if (!(png_ptr->row_number & 1))
            {
                png_read_finish_row(png_ptr);
                return;
            }
            break;
        }
    }
#endif

    if (!(png_ptr->mode & PNG_HAVE_IDAT))
        png_error(png_ptr, "Invalid attempt to read row data");

    png_ptr->zstream.next_out = png_ptr->row_buf;
    png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
    do
    {
        if (!(png_ptr->zstream.avail_in))
        {
            while (!png_ptr->idat_size)
            {
                png_byte chunk_length[4];

                png_crc_finish(png_ptr, 0);

                png_read_data(png_ptr, chunk_length, 4);
                png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);

                png_reset_crc(png_ptr);
                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
                if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
                    png_error(png_ptr, "Not enough image data");
            }
            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
            png_ptr->zstream.next_in = png_ptr->zbuf;
            if (png_ptr->zbuf_size > png_ptr->idat_size)
                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
            png_crc_read(png_ptr, png_ptr->zbuf,
                         (png_size_t)png_ptr->zstream.avail_in);
            png_ptr->idat_size -= png_ptr->zstream.avail_in;
        }
        ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
        if (ret == Z_STREAM_END)
        {
            if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
                    png_ptr->idat_size)
                png_error(png_ptr, "Extra compressed data");
            png_ptr->mode |= PNG_AFTER_IDAT;
            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
            break;
        }
        if (ret != Z_OK)
            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
                      "Decompression error");

    } while (png_ptr->zstream.avail_out);

    png_ptr->row_info.color_type = png_ptr->color_type;
    png_ptr->row_info.width = png_ptr->iwidth;
    png_ptr->row_info.channels = png_ptr->channels;
    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
                                 png_ptr->row_info.width);

    if(png_ptr->row_buf[0])
        png_read_filter_row(png_ptr, &(png_ptr->row_info),
                            png_ptr->row_buf + 1, png_ptr->prev_row + 1,
                            (int)(png_ptr->row_buf[0]));

    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
                     png_ptr->rowbytes + 1);

#if defined(PNG_MNG_FEATURES_SUPPORTED)
    if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
            (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
    {

        png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
    }
#endif


    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
        png_do_read_transformations(png_ptr);

#if defined(PNG_READ_INTERLACING_SUPPORTED)

    if (png_ptr->interlaced &&
            (png_ptr->transformations & PNG_INTERLACE))
    {
        if (png_ptr->pass < 6)
            png_do_read_interlace(png_ptr);

        if (dsp_row != NULL)
            png_combine_row(png_ptr, dsp_row,
                            png_pass_dsp_mask[png_ptr->pass]);
        if (row != NULL)
            png_combine_row(png_ptr, row,
                            png_pass_mask[png_ptr->pass]);
    }
    else
#endif
    {
        if (row != NULL)
            png_combine_row(png_ptr, row, 0xff);
        if (dsp_row != NULL)
            png_combine_row(png_ptr, dsp_row, 0xff);
    }
    png_read_finish_row(png_ptr);

    if (png_ptr->read_row_fn != NULL)
        (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
}
Exemplo n.º 22
0
Arquivo: deflate.c Projeto: ezc/elinks
static int
deflate_read(struct stream_encoded *stream, unsigned char *buf, int len)
{
	struct deflate_enc_data *data = (struct deflate_enc_data *) stream->data;
	int err = 0;
	int l = 0;

	if (!data) return -1;

	assert(len > 0);

	if (data->last_read) return 0;

	data->deflate_stream.avail_out = len;
	data->deflate_stream.next_out = buf;

	do {
		if (data->deflate_stream.avail_in == 0) {
			l = safe_read(data->fdread, data->buf,
			                  ELINKS_DEFLATE_BUFFER_LENGTH);

			if (l == -1) {
				if (errno == EAGAIN)
					break;
				else
					return -1; /* I/O error */
			} else if (l == 0) {
				/* EOF. It is error: we wait for more bytes */
				return -1;
			}

			data->deflate_stream.next_in = data->buf;
			data->deflate_stream.avail_in = l;
		}
restart:
		err = inflate(&data->deflate_stream, Z_SYNC_FLUSH);
		if (err == Z_DATA_ERROR && !data->after_first_read
		&& data->deflate_stream.next_out == buf) {
			/* RFC 2616 requires a zlib header for
			 * "Content-Encoding: deflate", but some HTTP
			 * servers (Microsoft-IIS/6.0 at blogs.msdn.com,
			 * and reportedly Apache with mod_deflate) omit
			 * that, causing Z_DATA_ERROR.  Clarification of
			 * the term "deflate" has been requested for the
			 * next version of HTTP:
			 * http://www3.tools.ietf.org/wg/httpbis/trac/ticket/73
			 *
			 * Try to recover by telling zlib not to expect
			 * the header.  If the error does not happen on
			 * the first inflate() call, then it is too late
			 * to recover because ELinks may already have
			 * discarded part of the input data.
			 *
			 * TODO: This fallback to raw DEFLATE is currently
			 * enabled for "Content-Encoding: gzip" too.  It
			 * might be better to fall back to no compression
			 * at all, because Apache can send that header for
			 * uncompressed *.gz.md5 files.  */
			data->after_first_read = 1;
			inflateEnd(&data->deflate_stream);
			data->deflate_stream.avail_out = len;
			data->deflate_stream.next_out = buf;
			data->deflate_stream.next_in = data->buf;
			data->deflate_stream.avail_in = l;
			err = inflateInit2(&data->deflate_stream, -MAX_WBITS);
			if (err == Z_OK) goto restart;
		}
		data->after_first_read = 1;
		if (err == Z_STREAM_END) {
			data->last_read = 1;
			break;
		} else if (err != Z_OK) {
			data->last_read = 1;
			break;
		}
	} while (data->deflate_stream.avail_out > 0);

	assert(len - data->deflate_stream.avail_out == data->deflate_stream.next_out - buf);
	return len - data->deflate_stream.avail_out;
}
Exemplo n.º 23
0
bool GELFServer::decompress(QByteArray &input, QByteArray &output)
{
    if (input.length() > 0) {
        // Prepare inflater status
        z_stream strm;
        strm.zalloc = Z_NULL;
        strm.zfree = Z_NULL;
        strm.opaque = Z_NULL;
        strm.avail_in = 0;
        strm.next_in = Z_NULL;
        // Initialize inflater
        int ret = inflateInit2(&strm, 32 + MAX_WBITS);
        if (ret != Z_OK)
            return false;
        // Extract pointer to input data
        char *input_data = input.data();
        int input_data_left = input.length();
        // Decompress data until available
        do {
            // Determine current chunk size
            int chunk_size = qMin(GZIP_CHUNK_SIZE, input_data_left);
            // Check for termination
            if (chunk_size <= 0)
                break;
            // Set inflater references
            strm.next_in = (unsigned char *)input_data;
            strm.avail_in = chunk_size;
            // Update interval variables
            input_data += chunk_size;
            input_data_left -= chunk_size;

            // Inflate chunk and cumulate output
            do {
                // Declare vars
                char out[GZIP_CHUNK_SIZE];

                // Set inflater references
                strm.next_out = (unsigned char *)out;
                strm.avail_out = GZIP_CHUNK_SIZE;

                // Try to inflate chunk
                ret = inflate(&strm, Z_NO_FLUSH);

                switch (ret) {
                case Z_NEED_DICT:
                    qWarning() << this << "Z_NEED_DICT";
                    ret = Z_DATA_ERROR;
                case Z_DATA_ERROR:
                    qWarning() << this << "Z_DATA_ERROR";
                case Z_MEM_ERROR:
                    qWarning() << this << "Z_MEM_ERROR";
                case Z_STREAM_ERROR:
                    qWarning() << this << "Z_STREAM_ERROR";
                    // Clean-up
                    inflateEnd(&strm);
                    // Return
                    return false;
                }

                // Determine decompressed size
                int have = (GZIP_CHUNK_SIZE - strm.avail_out);

                // Cumulate result
                if (have > 0) output.append((char *)out, have);
            } while (strm.avail_out == 0);
        } while (ret != Z_STREAM_END);

        // Clean-up
        inflateEnd(&strm);

        // Return
        return (ret == Z_STREAM_END);
    } else {
        return true;
    }
}
Exemplo n.º 24
0
size_t parsePdfObj( size_t startPos, uint8_t *buf, size_t endPos, int dataType, struct pdfObject *curObjPtr ) {
  size_t curPos = startPos, bufOffset = 0, sPos;
  uint8_t tmpByte = 0, status = 0, *destBuf;
  int offset = 0, objNum = 0, objRev = 0, count = 0, getNum = 0, i;
  char tmpStr[1024];
  char tmpBuf[4096];
  struct pdfObject *tmpObjPtr;

  /*
   * parse this object
   */

  if ( config->verbose )
    printf( ">> %lu/%lu [%s]\n", startPos, endPos, typeStrings[dataType] );

  /*
   * loop until we are at the end
   */

  while ( curPos < endPos ) {
    if ( dataType EQ PDF_TYPE_NONE ) {
#ifdef DEBUG
      if ( config->debug >= 5 )
	hexDump( curPos, buf+curPos, 64 );
#endif
      if ( buf[curPos] EQ ' ' | buf[curPos] EQ '\r' | buf[curPos] EQ '\n' | buf[curPos] EQ '\t' ) {
	/* white space */
	curPos++;
      } else if ( buf[curPos] EQ '<' ) {
	if ( buf[curPos+1] EQ '<' ) { /* dictionary */
	  curPos+=2;
	  if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	    return FAILED;
	  }
	  curObjPtr->type = PDF_TYPE_DICTIONARY;
	  curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_DICTIONARY, curObjPtr );
	} else { /* hex string */
	  curPos++;
	  if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	    return FAILED;
	  }
	  curObjPtr->type = PDF_TYPE_HEXSTRING; 
	  curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_HEXSTRING, curObjPtr );
	}
      } else if ( buf[curPos] EQ '(' ) { /* string */
	curPos++;
	if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	  return FAILED;
	}
	curObjPtr->type = PDF_TYPE_STRING; 
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_STRING, curObjPtr );
      } else if ( buf[curPos] EQ '/' ) { /* label */
	curPos++;
	if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	  return FAILED;
	}
	curObjPtr->type = PDF_TYPE_NAME; 
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_NAME, curObjPtr );
      } else if ( buf[curPos] EQ '[' ) {
	/* array */
	curPos++;
	if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	  return FAILED;
	}
	curObjPtr->type = PDF_TYPE_ARRAY; 
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_ARRAY, curObjPtr );
      } else if ( sscanf( buf+curPos, "%d %d %n%s", &objNum, &objRev, &offset, tmpStr ) EQ 3 ) { /* named object */
	if ( strncmp( tmpStr, "obj", 3 ) EQ 0 ) {
	  printf( "Object: %d %d\n", objNum, objRev );
	  curPos += ( offset + 3 );
	  if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	    return FAILED;
	  }
	  curObjPtr->type = PDF_TYPE_OBJECT;
	  curObjPtr->num = objNum;
	  curObjPtr->gen = objRev;
	  curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_OBJECT, curObjPtr );
	} else if ( tmpStr[0] EQ 'R' ) {
	  printf( "ObjRef: %d %d\n", objNum, objRev );
	  curPos += ( offset + 1 );
	  if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	    return FAILED;
	  }
	  curObjPtr->type = PDF_TYPE_REFERENCE;
	  curObjPtr->num = objNum;
	  curObjPtr->gen = objRev;
	  curObjPtr = curObjPtr->parent;
	  /* once we have loaded all objects, we will link all references to their real objects */
	} else {
	  if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	    return FAILED;
	  }
	  curObjPtr->type = PDF_TYPE_INTNUM;
	  curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_INTNUM, curObjPtr );
	}
      } else if ( isdigit( buf[curPos] ) || ( buf[curPos] EQ '-' ) || ( buf[curPos] EQ '+' ) ) { /* number */
	if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	  return FAILED;
	}
	curObjPtr->type = PDF_TYPE_INTNUM;
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_INTNUM, curObjPtr );
      } else if ( ( buf[curPos] EQ 't' ) || ( buf[curPos] EQ 'f' ) ) { /* boolean number */
	if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	  return FAILED;
	}
	curObjPtr->type = PDF_TYPE_BOOL;
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_BOOL, curObjPtr );
      } else if ( buf[curPos] EQ '%' ) { /* comment */
	curPos++;
        /* check if this is EOF */
        if ( strncmp( buf+curPos, "%EOF\n", 5 ) EQ 0 ) {
            curPos += 5;
            printf( "EOF\n" );
            curObjPtr->type = PDF_TYPE_EOF;
            curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_EOF, curObjPtr );

        } else {
            if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
                return FAILED;
            }
            curObjPtr->type = PDF_TYPE_COMMENT;
            curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_COMMENT, curObjPtr );
        }
      } else if ( strncmp( buf+curPos, "stream", 6 ) EQ 0 ) { /* stream */
	curPos += 6;
	if ( buf[curPos] EQ '\r' )
	  curPos++;
	if ( buf[curPos] EQ '\n' )
	  curPos++;
	if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	  return FAILED;
	}
	curObjPtr->type = PDF_TYPE_STREAM;
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_STREAM, curObjPtr );
      } else if ( strncmp( buf+curPos, "obj", 3 ) EQ 0 ) {
	/* object */
	curPos += 3;
	if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	  return FAILED;
	}
	curObjPtr->type = PDF_TYPE_OBJECT;
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_OBJECT, curObjPtr );
      } else if ( strncmp( buf+curPos, "xref", 4 ) EQ 0 ) {
          
	/* start of footer */
	curPos += 4;
	if ( ( curObjPtr = insertPdfObject( curObjPtr ) ) EQ NULL ) {
	  return FAILED;
	}
	curObjPtr->type = PDF_TYPE_FOOTER;
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_FOOTER, curObjPtr );
        
      } else if ( strncmp( buf+curPos, "startxref", 9 ) EQ 0 ) {
        curPos += 9;  
        curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_NONE, curObjPtr );
      } else if ( strncmp( buf+curPos, "endobj", 6 ) EQ 0 ) {
	return( curPos );

      } else if ( buf[curPos] EQ ']' ) {
	return( curPos );

      } else if ( strncmp( buf+curPos, ">>", 2 ) EQ 0 ) {
	return( curPos );

      } else if ( buf[curPos] EQ '>' ) {
	return( curPos );

      } else {
          if ( isprint( buf[curPos] ) )
              printf( "%c", buf[curPos] );
          else
              printf( "." );
	curPos++;
      }
    } else if ( dataType EQ PDF_TYPE_EOF ) {
        /* all data after EOF is suspect */
	if ( config->write ) {
	  writeStream( curPos, buf+curPos, endPos - curPos );
	} else
	  hexDump( curPos, buf+curPos, endPos - curPos );
        curPos = endPos;
    } else if ( dataType EQ PDF_TYPE_REALNUM ) {
      /* 3.4 = realNum */
      sPos = curPos;
      if ( ( buf[curPos] EQ '-' ) || ( buf[curPos] EQ '+' ) ) {
	tmpStr[curPos-sPos] = buf[curPos];
	curPos++;
      }
      while( isdigit( buf[curPos] ) || buf[curPos] EQ '.' ) {
	tmpStr[curPos-sPos] = buf[curPos];
	curPos++;
      }
      tmpStr[curPos-sPos] = '\0';
      printf( "Real Number: %s\n", safePrint( tmpBuf, sizeof( tmpBuf ), tmpStr ) );
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_INTNUM ) {
      /* 343 = intNum */
      sPos = curPos;

      if ( ( buf[curPos] EQ '-' ) || ( buf[curPos] EQ '+' ) )
	curPos++;

      while( ( isdigit( buf[curPos] ) ) || ( buf[curPos] EQ '.' ) ) {
	if ( buf[curPos] EQ '.' ) {
	  curObjPtr->type = PDF_TYPE_REALNUM;
	  return parsePdfObj( sPos, buf, endPos, PDF_TYPE_REALNUM, curObjPtr );
	}
	curPos++;
      }
      printf( "Integer: %d\n", atoi( buf+sPos ) );
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_BOOL ) {
      /* true | false = bool */

      if ( strncmp( buf+curPos, "true", 4 ) EQ 0 ) {
	/* true */
	printf( "Boolean: true\n" );
	curPos += 4;
      } else if ( strncmp( buf+curPos, "false", 5 ) EQ 0 ) {
	/* false */
	printf( "Boolean: false\n" );
	curPos += 5;
      } else
	curPos++;
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_EOL ) {
      /* \n\r | \n | \n\r\n\r = EOL */
      while( ( buf[curPos] EQ '\n' ) || ( buf[curPos] EQ '\r' ) ) {
	curPos++;
      }
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_COMMENT ) {
      /* % ... EOL = comment */
      sPos = curPos;
      while( ( buf[curPos] != '\r' ) && ( buf[curPos] != '\n' ) ) {
	tmpStr[curPos-sPos] = buf[curPos];
	curPos++;
      }
      tmpStr[curPos-sPos] = '\0';
      printf( "Comment: %s\n", safePrint( tmpBuf, sizeof( tmpBuf ), tmpStr ) );
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_NAME ) {
      /* / ... = name */
      sPos = curPos;
      while( ( buf[curPos] != '\r' ) &&
	     ( buf[curPos] != '\n' ) &&
	     ( buf[curPos] != ' ' ) &&
	     ( buf[curPos] != '[' ) &&
	     ( buf[curPos] != '<' ) &&
	     ( buf[curPos] != '/' ) &&
	     ( buf[curPos] != '(' ) &&
	     ( buf[curPos] != '>' ) &&
	     ( buf[curPos] != ']' ) &&
	     ( buf[curPos] != ')' ) ) {
	/* process label */
	tmpStr[curPos-sPos] = buf[curPos];
	curPos++;
      }
      tmpStr[curPos-sPos] = '\0';
      printf( "Name: %s\n", safePrint( tmpBuf, sizeof( tmpBuf ), tmpStr ) );
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_STRING ) {
      /* ( ... ) = literalString */
      /* XXX add octal notation '\000' */
      /* XXX handle escaped characters */
      while( buf[curPos] EQ ' ' ) {
	curPos++;
      }
      sPos = curPos;
      if ( strncmp( buf+curPos, "254 255", 7 ) EQ 0 ) {
	curObjPtr->type = PDF_TYPE_UTFSTRING;
	return parsePdfObj( curPos, buf, endPos, PDF_TYPE_UTFSTRING, curObjPtr );
      } else if ( ( buf[curPos] EQ 'D' ) && ( buf[curPos+1] EQ ':' ) ) {
	curObjPtr->type = PDF_TYPE_DATESTRING;
	return parsePdfObj( curPos, buf, endPos, PDF_TYPE_DATESTRING, curObjPtr );
      }

      while( buf[curPos] != ')' ) {
	tmpStr[curPos-sPos] = buf[curPos];
	curPos++;
      }
      tmpStr[curPos-sPos] = '\0';
      printf( "String: %s\n", safePrint( tmpBuf, sizeof( tmpBuf ), tmpStr ) );
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos + 1 );

    } else if ( dataType EQ PDF_TYPE_UTFSTRING ) {
      /* ( 254 255 ... ) = utf encoded literal string */
      while( sscanf( buf+curPos, "%u%n", (unsigned int *)&tmpByte, &offset ) EQ 1 ) {
	curPos += offset;
	if ( buf[curPos] EQ ' ' ) {
	  curPos++;
	}
      }
      while( buf[curPos] != ')' ) {
	curPos++;
      }
      curPos++;
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_DATESTRING ) {
      sPos = curPos;
      /* (D:YYYYMMDDHHmmSSOHH'mm') = date encoded literal string */
      while( buf[curPos] != ')' ) {
	tmpStr[curPos-sPos] = buf[curPos];
	curPos++;
      }
      curPos++;
      tmpStr[curPos-sPos] = '\0';
      printf( "Date String: %s\n", safePrint( tmpBuf, sizeof( tmpBuf ), tmpStr ) );
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_HEXSTRING ) {
      /* < ... > = hexString */
      count = 0;
      sPos = curPos;
      while( buf[curPos] != '>' ) {
	if ( isxdigit( buf[curPos] ) )
	  tmpStr[count++] = buf[curPos];
	curPos++;
      }
      /* append a zero is the string length is odd */
      if ( !( count % 2 ) EQ 0 ) {
	tmpStr[count++] = '0';
      }
      tmpStr[count] = '\0';
      curPos++;
      printf( "HEX String: %s\n", safePrint( tmpBuf, sizeof( tmpBuf ), tmpStr ) );
      for( i = 0, offset = 0; i < count; i += 2 ) {
	tmpStr[offset++] = xtoi( tmpStr+i, 2 );
      }
      hexDump( 0, tmpStr, offset );
      printf( "HEX String: %s\n", safePrint( tmpBuf, sizeof( tmpBuf ), tmpStr ) );
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_UTFHEXSTRING ) {
      /* < fe ff ... > = utf encoded hex string */
      sPos = curPos;


    } else if ( dataType EQ PDF_TYPE_ARRAY ) {
      /* [ ... ] = array NOTE can be an array of any n objects */
      while( buf[curPos] != ']' ) {
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_NONE, curObjPtr );
      }
      curPos++;
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_DICTIONARY ) {
      /* << /Kids [ 1 0 R 1 0 R ]  = name tree */
      /*    /Names [ (key1) 1 0 R (key2) 2 0 R ] */
      /*    /Limits [ (firstKey) (lastKey) ] */
      /* << name ... >> = dictionary where key is a name and value can be any object */
      /* XXX organize into name, value pairs */
      while( strncmp( buf+curPos, ">>", 2 ) != 0 ) {
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_NONE, curObjPtr );
      }
      curPos += 2;
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );
      
    } else if ( dataType EQ PDF_TYPE_OBJECT ) {
      /* 3 0 obj ... endobj = turns any object into an indirect (referencable) object */
      /*                      3 = objNum, 0 = objRev */
      while ( strncmp( buf+curPos, "endobj", 6 ) != 0 ) {
	curPos = parsePdfObj( curPos, buf, endPos, PDF_TYPE_NONE, curObjPtr );
      }
      curPos += 6;
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[PDF_TYPE_OBJECT] );
      return( curPos );

    } else if ( dataType EQ PDF_TYPE_STREAM ) {
      /* XXX add code to associate the stream dictionary with the stream data */
      /* << ... >>EOLstream\n\r or \r ... \n\r endstream = stream */
      sPos = curPos;

      while( strncmp( buf+curPos, "endstream", 9 ) != 0 ) {
	curPos++;
      }

      printf( "Stream: %lu bytes\n", curPos - sPos );

      /* allocate buffer for decompressed stream */
      if ( ( destBuf = XMALLOC( ( curPos - sPos ) * 4 ) ) EQ NULL ) {
	fprintf( stderr, "ERR - Unable to allocate memory for stream\n" );
	exit( 1 );
      }
      XMEMSET( destBuf, 0, ( curPos-sPos ) * 4 );

      /* decompress the stream */
      z_stream zstrm;
      XMEMSET( &zstrm, 0, sizeof(zstrm) );
      zstrm.avail_in = curPos-sPos;
      zstrm.avail_out = ( curPos-sPos ) * 4;
      zstrm.next_in = buf+sPos;
      zstrm.next_out = destBuf;
      int rsti = inflateInit(&zstrm);
      if (rsti EQ Z_OK) {
	int rst2 = inflate (&zstrm, Z_FINISH);
	if (rst2 >= 0) {
	  if ( config->write ) {
	    writeStream( sPos, destBuf, zstrm.total_out );
	  } else
	    hexDump( 0, destBuf, zstrm.total_out );
	} else {
	  printf( "Stream did not decompress\n" );
	  if ( config->write ) {
	    writeStream( sPos, buf+sPos, curPos-sPos );
	  } else
	    hexDump( sPos, buf+sPos, curPos-sPos );
	}
      }

      XFREE( destBuf );

      curPos += 9;

      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      return( curPos );
      
    } else if ( dataType EQ PDF_TYPE_HEADER ) {
      /* %PDF-1.6EOL%nnnnEOL = file header where each n is > 128 to make file look binary */

    } else if ( dataType EQ PDF_TYPE_FOOTER ) {
      /* xref ... trailer ... startxref ... %%EOF = document footer */
      /* XXX making an asumption, big mistake */
      
      /* 0 271 */
      /* 0000000000 65535 f */
      /* 0000000015 00000 n */
      
      /* found the xref, now look for the trailer, startxref and finally the EOF */
      
      fprintf( stderr, "PDF Footer\n" );
      
      /* XXX need to parse xref table, may be multiple tables in the file */
      
      if ( strncmp( buf+curPos, "trailer", 7 ) EQ 0 ) {
          printf( "trailer\n" );
          curPos += 7;
      } else
          curPos++;
      
      if ( config->verbose )
	printf( "<< %lu/%lu [%s]\n", curPos, endPos, typeStrings[dataType] );
      
      return( curPos );
    }
  }

  return( curPos );
}
Exemplo n.º 25
0
/**
 * uncompress data and copy it to read buffer.
 * Returns true if data has been unpacked or no
 * compressed data is currently pending in the zread buffer.
 * This function closes the connection on error.
 * @param Idx Connection handle.
 * @return true on success, false otherwise.
 */
GLOBAL bool
Unzip_Buffer( CONN_ID Idx )
{
	int result;
	unsigned char unzipbuf[READBUFFER_LEN];
	int unzipbuf_used = 0;
	unsigned int z_rdatalen;
	unsigned int in_len;
	
	z_stream *in;

	assert( Idx > NONE );

	z_rdatalen = (unsigned int)array_bytes(&My_Connections[Idx].zip.rbuf);
	if (z_rdatalen == 0)
		return true;

	in = &My_Connections[Idx].zip.in;

	in->next_in = array_start(&My_Connections[Idx].zip.rbuf);
	assert(in->next_in != NULL);

	in->avail_in = z_rdatalen;
	in->next_out = unzipbuf;
	in->avail_out = (uInt)sizeof unzipbuf;

#ifdef DEBUG_ZIP
	Log(LOG_DEBUG, "in->avail_in %d, in->avail_out %d",
		in->avail_in, in->avail_out);
#endif
	result = inflate( in, Z_SYNC_FLUSH );
	if( result != Z_OK )
	{
		Log(LOG_ALERT, "Decompression error: %s (code=%d, ni=%d, ai=%d, no=%d, ao=%d)!?", in->msg, result, in->next_in, in->avail_in, in->next_out, in->avail_out);
		Conn_Close(Idx, "Decompression error!", NULL, false);
		return false;
	}

	assert(z_rdatalen >= in->avail_in);
	in_len = z_rdatalen - in->avail_in;
	unzipbuf_used = READBUFFER_LEN - in->avail_out;
#ifdef DEBUG_ZIP
	Log(LOG_DEBUG, "unzipbuf_used: %d - %d = %d", READBUFFER_LEN,
		in->avail_out, unzipbuf_used);
#endif
	assert(unzipbuf_used <= READBUFFER_LEN);
	if (!array_catb(&My_Connections[Idx].rbuf, (char*) unzipbuf,
			(size_t)unzipbuf_used)) {
		Log (LOG_ALERT, "Decompression error: can't copy data!?");
		Conn_Close(Idx, "Decompression error!", NULL, false);
		return false;
	}
	if( in->avail_in > 0 ) {
		array_moveleft(&My_Connections[Idx].zip.rbuf, 1, in_len );
	} else {
		array_trunc( &My_Connections[Idx].zip.rbuf );
		My_Connections[Idx].zip.bytes_in += unzipbuf_used;
	}

	return true;
} /* Unzip_Buffer */
Exemplo n.º 26
0
/* do_zstream(data_stream, zsync_stream, buffer, buffer_len)
 * Constructs the zmap for a compressed data stream, in a temporary file.
 * The compressed data is from data_stream, except that some bytes have already
 * been read from it - those are supplied in buffer (buffer_len of them).
 * The zsync block checksums are written to zsync_stream, and the zmap is
 * written to a temp file and the handle returned in the global var zmap.
 */
void do_zstream(FILE * fin, FILE * fout, const char *bufsofar, size_t got) {
    z_stream zs;
    Bytef *inbuf = malloc(blocksize);
    const size_t inbufsz = blocksize;
    Bytef *outbuf = malloc(blocksize);
    int eoz = 0;
    int header_bits;
    long long prev_in = 0;
    long long prev_out = 0;
    long long midblock_in = 0;
    long long midblock_out = 0;
    int want_zdelta = 0;

    if (!inbuf || !outbuf) {
        fprintf(stderr, "memory allocation failure\n");
        exit(1);
    }

    /* Initialize decompressor */
    zs.zalloc = Z_NULL;
    zs.zfree = Z_NULL;
    zs.opaque = NULL;
    zs.next_in = inbuf;
    zs.avail_in = 0;
    zs.total_in = 0;
    zs.next_out = outbuf;
    zs.avail_out = 0;
    if (inflateInit2(&zs, -MAX_WBITS) != Z_OK)
        exit(-1);

    {   /* Skip gzip header and do initial buffer fill */
        const char *p = skip_zhead(bufsofar);

        {   /* Store hex version of gzip header in zhead */
            int header_bytes = p - bufsofar;
            int i;

            header_bits = 8 * header_bytes;
            got -= header_bytes;

            zhead = malloc(1 + 2 * header_bytes);
            for (i = 0; i < header_bytes; i++)
                sprintf(zhead + 2 * i, "%02x", (unsigned char)bufsofar[i]);
        }
        if (got > inbufsz) {
            fprintf(stderr,
                    "internal failure, " SIZE_T_PF " > " SIZE_T_PF
                    " input buffer available\n", got, inbufsz);
            exit(2);
        }

        /* Copy any remaining already-read data from the buffer to the
         * decompressor input buffer */
        memcpy(inbuf, p, got);
        zs.avail_in = got;

        /* Fill the buffer up to offset inbufsz of the input file - we want to
         * try and keep the input blocks aligned with block boundaries in the
         * underlying filesystem and physical storage */
        if (inbufsz > got + (header_bits / 8))
            zs.avail_in +=
                fread(inbuf + got, 1, inbufsz - got - (header_bits / 8), fin);
    }

    /* Start the zmap. We write into a temp file, which the caller then copies into the zsync file later. */
    zmap = tmpfile();
    if (!zmap) {
        perror("tmpfile");
        exit(2);
    }

    /* We are past the header, so we are now at the start of the first block */
    write_zmap_delta(&prev_in, &prev_out, header_bits, zs.total_out, 1);
    zs.avail_out = blocksize;

    /* keep going until the end of the compressed stream */
    while (!eoz) {
        /* refill input buffer if empty */
        if (zs.avail_in == 0) {
            int rc = fread(inbuf, 1, inbufsz, fin);
            if (rc < 0) {
                perror("read");
                exit(2);
            }

            /* Still expecting data (!eoz and avail_in == 0) but none there. */
            if (rc == 0) {
                fprintf(stderr, "Premature end of compressed data.\n");
                exit(1);
            }

            zs.next_in = inbuf;
            zs.avail_in = rc;
        }
        {
            int rc;

            /* Okay, decompress more data from inbuf to outbuf.
             * Z_BLOCK means that decompression will halt if we reach the end of a
             *  compressed block in the input file.
             * And decompression will also stop if outbuf is filled (at which point
             *  we have a whole block of uncompressed data and so should write its
             *  checksums)
             *
             * Terminology note:
             * Compressed block   = zlib block (stream of bytes compressed with
             *                      common huffman table)
             * Uncompressed block = Block of blocksize bytes (starting at an
             *                      offset that is a whole number of blocksize
             *                      bytes blocks from the start of the
             *                      (uncompressed) data. I.e. a zsync block.
             */
            rc = inflate(&zs, Z_BLOCK);
            switch (rc) {
            case Z_STREAM_END:
                eoz = 1;
            case Z_BUF_ERROR:  /* Not really an error, just means we provided stingy buffers */
            case Z_OK:
                break;
            default:
                fprintf(stderr, "zlib error %s\n", zs.msg);
                exit(1);
            }

            /* If the output buffer is filled, i.e. we've now got a whole block of uncompressed data. */
            if (zs.avail_out == 0 || rc == Z_STREAM_END) {
                /* Add to the running SHA1 of the entire file. */
                SHA1Update(&shactx, outbuf, blocksize - zs.avail_out);

                /* Completed a block; write out its checksums */
                write_block_sums(outbuf, blocksize - zs.avail_out, fout);

                /* Clear the decompressed data buffer, ready for the next block of uncompressed data. */
                zs.next_out = outbuf;
                zs.avail_out = blocksize;

                /* Having passed a block boundary in the uncompressed data */
                want_zdelta = 1;
            }

            /* If we have reached a block boundary in the compressed data */
            if (zs.data_type & 128 || rc == Z_STREAM_END) {
                /* write out info on this block */
                write_zmap_delta(&prev_in, &prev_out,
                                 header_bits + in_position(&zs), zs.total_out,
                                 1);

                midblock_in = midblock_out = 0;
                want_zdelta = 0;
            }

            /* If we passed a block boundary in the uncompressed data, record the
             * next available point at which we could stop or start decompression.
             * Write a zmap delta with the 1st when we see the 2nd, etc */
            if (want_zdelta && inflateSafePoint(&zs)) {
                long long cur_in = header_bits + in_position(&zs);
                if (midblock_in) {
                    write_zmap_delta(&prev_in, &prev_out, midblock_in,
                                     midblock_out, 0);
                }
                midblock_in = cur_in;
                midblock_out = zs.total_out;
                want_zdelta = 0;
            }
        }
    }

    /* Record uncompressed length */
    len += zs.total_out;
    fputc('\n', fout);
    /* Move back to the start of the zmap constructed, ready for the caller to read it back in */
    rewind(zmap);

    /* Clean up */
    inflateEnd(&zs);
    free(inbuf);
    free(outbuf);
}
Exemplo n.º 27
0
/*
 *
 * Decode a frame
 *
 */
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)
{
    CamtasiaContext * const c = avctx->priv_data;
    const unsigned char *encoded = buf;
    unsigned char *outptr;
#ifdef CONFIG_ZLIB
    int zret; // Zlib return code
#endif
    int len = buf_size;

    if(c->pic.data[0])
            avctx->release_buffer(avctx, &c->pic);

    c->pic.reference = 1;
    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
    if(avctx->get_buffer(avctx, &c->pic) < 0){
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }

    outptr = c->pic.data[0]; // Output image pointer

#ifdef CONFIG_ZLIB
    zret = inflateReset(&(c->zstream));
    if (zret != Z_OK) {
        av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
        return -1;
    }
#ifdef __CW32__
    c->zstream.next_in = (unsigned char*)encoded;
#else
    c->zstream.next_in = encoded;
#endif
    c->zstream.avail_in = len;
    c->zstream.next_out = c->decomp_buf;
    c->zstream.avail_out = c->decomp_size;
    zret = inflate(&(c->zstream), Z_FINISH);
    // Z_DATA_ERROR means empty picture
    if ((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
        av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
        return -1;
    }


    if(zret != Z_DATA_ERROR)
        decode_rle(c, c->zstream.avail_out);

    /* make the palette available on the way out */
    if (c->avctx->pix_fmt == PIX_FMT_PAL8) {
        memcpy(c->pic.data[1], c->avctx->palctrl->palette, AVPALETTE_SIZE);
        if (c->avctx->palctrl->palette_changed) {
            c->pic.palette_has_changed = 1;
            c->avctx->palctrl->palette_changed = 0;
        }
    }

#else
    av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
    return -1;
#endif

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = c->pic;

    /* always report that the buffer was completely consumed */
    return buf_size;
}
Exemplo n.º 28
0
Arquivo: gzio.c Projeto: rblake/seg3d2
/*
** _nrrdGzRead()
**
** Reads the given number of uncompressed bytes from the compressed file.
** Returns the number of bytes actually read (0 for end of file).
*/
int
_nrrdGzRead(gzFile file, voidp buf, unsigned int len, unsigned int* read) {
  char me[]="_nrrdGzRead", err[BIFF_STRLEN];
  _NrrdGzStream *s = (_NrrdGzStream*)file;
  Bytef *start = (Bytef*)buf; /* starting point for crc computation */
  Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */

  if (s == NULL || s->mode != 'r') {
    sprintf(err, "%s: invalid stream or file mode", me);
    biffAdd(NRRD, err);
    *read = 0;
    return 1;
  }

  if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) {
    sprintf(err, "%s: data read error", me);
    biffAdd(NRRD, err);
    *read = 0;
    return 1;
  }

  if (s->z_err == Z_STREAM_END) {
    *read = 0;
    return 0;  /* EOF */
  }

  next_out = (Byte*)buf;
  s->stream.next_out = (Bytef*)buf;
  s->stream.avail_out = len;

  while (s->stream.avail_out != 0) {

    if (s->transparent) {
      /* Copy first the lookahead bytes: */
      uInt n = s->stream.avail_in;
      if (n > s->stream.avail_out) n = s->stream.avail_out;
      if (n > 0) {
        memcpy(s->stream.next_out, s->stream.next_in, n);
        next_out += n;
        s->stream.next_out = next_out;
        s->stream.next_in   += n;
        s->stream.avail_out -= n;
        s->stream.avail_in  -= n;
      }
      if (s->stream.avail_out > 0) {
        s->stream.avail_out -= (uInt)fread(next_out, 1, s->stream.avail_out,
                                           s->file);
      }
      len -= s->stream.avail_out;
      s->stream.total_in  += len;
      s->stream.total_out += len;
      if (len == 0) s->z_eof = 1;
      *read = len;
      return 0;
    }
    if (s->stream.avail_in == 0 && !s->z_eof) {

      errno = 0;
      s->stream.avail_in = (uInt)fread(s->inbuf, 1, _NRRD_Z_BUFSIZE, s->file);
      if (s->stream.avail_in == 0) {
        s->z_eof = 1;
        if (ferror(s->file)) {
          s->z_err = Z_ERRNO;
          break;
        }
      }
      s->stream.next_in = s->inbuf;
    }
    s->z_err = inflate(&(s->stream), Z_NO_FLUSH);

    if (s->z_err == Z_STREAM_END) {
      /* Check CRC and original size */
      s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
      start = s->stream.next_out;

      if (_nrrdGzGetLong(s) != s->crc) {
        s->z_err = Z_DATA_ERROR;
      } else {
        (void)_nrrdGzGetLong(s);
        /* The uncompressed length returned by above getlong() may
         * be different from s->stream.total_out) in case of
         * concatenated .gz files. Check for such files:
         */
        _nrrdGzCheckHeader(s);
        if (s->z_err == Z_OK) {
          uLong total_in = s->stream.total_in;
          uLong total_out = s->stream.total_out;

          inflateReset(&(s->stream));
          s->stream.total_in = total_in;
          s->stream.total_out = total_out;
          s->crc = crc32(0L, Z_NULL, 0);
        }
      }
    }
    if (s->z_err != Z_OK || s->z_eof) break;
  }
  s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));

  *read = len - s->stream.avail_out;
  return 0;
}
Exemplo n.º 29
0
void unpack_header(const char *input_file_name,  struct _TAG_OBJECT_INFO *oi) {

  FILE *input_file = fopen(input_file_name, "rb");
  if (input_file == NULL) {
    ERROR("%s", input_file_name);
  }


  Bytef input_buf[65536];
  char output_buf[65536];
  char *cp;
  z_stream stream;
  cp = output_buf;
  // メモリの確保・解放は zlib に任せます.
  stream.zalloc = Z_NULL;
  stream.zfree = Z_NULL;
  stream.opaque = Z_NULL;

  // .next_in, .avail_in は inflateInit(), inflateInit2() を呼び出す前に
  // 初期化しておく必要があります.
  stream.next_in = Z_NULL;
  stream.avail_in = 0;

  int retInit = inflateInit(&stream);
  if (retInit != Z_OK) {
    // inflateInit(), inflateInit2() はエラーが起きても .msg を更新しません.
    // エラーメッセージの取得には zError() を利用することになります.
    ERROR("%s", zError(retInit));
  }

  int ret = Z_OK;
  while (ret != Z_STREAM_END) {
    stream.avail_in = fread(input_buf, 1, sizeof(input_buf), input_file);
    if (ferror(input_file) != 0) {
      ERROR("failed to read from file");
    }
    if (stream.avail_in == 0) {
      // 入力が既に尽きている状態であれば,意図していないファイルの終端に
      // 到達したことになります.
      ERROR("unexpected end of file");
    }
    stream.next_in = input_buf;
    while ((stream.avail_out == 0) && (ret != Z_STREAM_END)) {
      stream.next_out = cp;
      stream.avail_out = sizeof(output_buf);
      ret = inflate(&stream, Z_NO_FLUSH);
      if (ret == Z_MEM_ERROR) {
          ERROR("%s", stream.msg);
      }

    } ;
  };

  int i = 0;
  while (*(cp) != ' ') {
    oi->type[i++] = *(cp++);
  }
  oi->type[i] = 0;


  i = 0;
  while (*cp) {
    oi->size[i++] = *(cp++);
  }
  oi->size[i] = 0;

  int retEnd = inflateEnd(&stream);
  if (retEnd != Z_OK) {
    // deflateEnd() はエラーが起きても .msg を更新しません.
    // エラーメッセージの取得には zError() を利用することになります.
    ERROR("%s", zError(retEnd));
  }

  if (fclose(input_file) != 0) {
    ERROR("%s", input_file_name);
  }


}
Exemplo n.º 30
0
/* Zlib-specific Decompression function. */
static inline int SnortDecompressZlib(decompress_state_t *state, uint8_t *input, uint32_t input_len,
                               uint8_t *output, uint32_t output_bufsize, uint32_t *output_len)
{
    z_streamp zlib_stream = (z_streamp) state->lib_info;
    int zlib_ret;
    int snort_ret = SNORT_DECOMPRESS_OK;

    if (zlib_stream == NULL)
        return SNORT_DECOMPRESS_BAD_ARGUMENT; // Uninitialized state object.

    /* The call to inflateInit() requires some data to be provided.
       That's why the call isn't done in SnortDecompressInit(). */
    if (state->flags & SNORT_ZLIB_INIT_NEEDED)
    {
        if (input == NULL)
            return SNORT_DECOMPRESS_BAD_ARGUMENT;

        zlib_stream->next_in = input;
        zlib_stream->avail_in = input_len;

        /* Zlib init has a funky parameter for window size.
           ZLIB_WBITS specifies that we'll inflate both Zlib & Gzip streams.
           DEFLATE_WBITS is needed for raw deflate streams w/o headers
           (as seen in HTTP). */
        if (state->type == COMPRESSION_TYPE_DEFLATE)
            zlib_ret = inflateInit2(zlib_stream, DEFLATE_WBITS);
        else
            zlib_ret = inflateInit2(zlib_stream, ZLIB_WBITS);
        state->lib_return = zlib_ret;

        state->flags &= ~SNORT_ZLIB_INIT_NEEDED;
    }
    /* If input is NULL, just continue decompressing from the last spot.
       This is how a caller would handle truncated output. */
    else if (input)
    {
        zlib_stream->next_in = input;
        zlib_stream->avail_in = input_len;
    }
        
    zlib_stream->next_out = output;
    zlib_stream->avail_out = output_bufsize;
    
    while (zlib_stream->avail_in > 0 && zlib_stream->avail_out > 0)
    {
        zlib_ret = inflate(zlib_stream, Z_SYNC_FLUSH);
        state->lib_return = zlib_ret;

        if (zlib_ret == Z_STREAM_END)
            break; // Not an error, just hit the end of compressed data.

        if (zlib_ret != Z_OK)
        {
            snort_ret = SNORT_DECOMPRESS_BAD_DATA;
            break;
        }
    }

    if ((zlib_stream->avail_in > 0 && zlib_stream->avail_out == 0) &&
        (snort_ret != SNORT_DECOMPRESS_BAD_DATA))
    {
        snort_ret = SNORT_DECOMPRESS_OUTPUT_TRUNC;
    }

    *output_len = output_bufsize - zlib_stream->avail_out;

    return snort_ret;
}