2014-08-10 16:13:12 +00:00
|
|
|
/* radare - LGPL - Copyright 2014 - pancake */
|
|
|
|
|
|
|
|
#include <r_util.h>
|
|
|
|
#include <zlib.h>
|
|
|
|
|
|
|
|
|
2014-09-07 20:55:15 +00:00
|
|
|
// set a maximum output buffer of 50MB
|
|
|
|
#define MAXOUT 50000000
|
2014-08-10 16:24:00 +00:00
|
|
|
|
2014-09-05 11:44:49 +00:00
|
|
|
R_API ut8 *r_inflate(const ut8 *src, int srcLen, int *dstLen) {
|
2014-09-07 20:55:15 +00:00
|
|
|
int err = 0;
|
|
|
|
int out_size = 0;
|
|
|
|
ut8 *dst = NULL;
|
|
|
|
z_stream stream;
|
|
|
|
|
|
|
|
if( srcLen <= 0 ) {
|
2014-08-10 16:24:00 +00:00
|
|
|
return NULL;
|
2014-09-07 20:55:15 +00:00
|
|
|
}
|
2014-08-10 16:13:12 +00:00
|
|
|
|
2014-09-07 20:55:15 +00:00
|
|
|
memset (&stream, 0, sizeof (z_stream));
|
|
|
|
stream.avail_in = srcLen;
|
|
|
|
stream.next_in = (Bytef *) src;
|
2014-08-10 16:13:12 +00:00
|
|
|
|
2014-09-07 20:55:15 +00:00
|
|
|
stream.zalloc = Z_NULL;
|
|
|
|
stream.zfree = Z_NULL;
|
|
|
|
stream.opaque = Z_NULL;
|
2014-08-10 16:13:12 +00:00
|
|
|
|
2014-09-05 11:44:49 +00:00
|
|
|
// + 32 tells zlib not to care whether the stream is a zlib or gzip stream
|
2014-09-07 20:55:15 +00:00
|
|
|
if( inflateInit2(&stream, MAX_WBITS + 32) != Z_OK ) {
|
2014-08-10 16:13:12 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-09-07 20:55:15 +00:00
|
|
|
do {
|
|
|
|
if( stream.avail_out == 0 ) {
|
|
|
|
if (! (dst = realloc(dst, stream.total_out + srcLen*2)))
|
|
|
|
goto err_exit;
|
|
|
|
|
|
|
|
out_size += srcLen*2;
|
|
|
|
|
|
|
|
if (out_size > MAXOUT)
|
|
|
|
goto err_exit;
|
|
|
|
|
|
|
|
stream.next_out = dst + stream.total_out;
|
|
|
|
stream.avail_out = srcLen * 2;
|
|
|
|
}
|
|
|
|
err = inflate(&stream, Z_FINISH);
|
|
|
|
switch (err) {
|
|
|
|
case Z_DATA_ERROR:
|
|
|
|
case Z_MEM_ERROR:
|
|
|
|
case Z_NEED_DICT:
|
|
|
|
goto err_exit;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} while ( err != Z_STREAM_END );
|
|
|
|
|
|
|
|
if( dstLen )
|
|
|
|
*dstLen = stream.total_out;
|
|
|
|
|
|
|
|
inflateEnd(&stream);
|
|
|
|
return dst;
|
|
|
|
|
|
|
|
err_exit:
|
|
|
|
inflateEnd(&stream);
|
|
|
|
free(dst);
|
2014-08-10 16:13:12 +00:00
|
|
|
return NULL;
|
|
|
|
}
|