1
0
mirror of https://github.com/upx/upx.git synced 2025-08-11 22:52:30 +08:00

Implemented the remaining missing pieces of compress_zlib.

This commit is contained in:
Markus F.X.J. Oberhumer
2006-11-21 17:19:24 +01:00
parent ef7beea334
commit a050f82f0e
6 changed files with 129 additions and 19 deletions

View File

@ -92,10 +92,20 @@ int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
#if defined(WITH_ZLIB)
const char *upx_zlib_version_string(void);
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
upx_callback_p cb,
int method, int level,
const upx_compress_config_t *cconf,
upx_compress_result_t *cresult );
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
upx_bytep dst, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult );
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
unsigned src_len, unsigned* dst_len,
int method,
const upx_compress_result_t *cresult );
#endif

View File

@ -28,6 +28,18 @@
#include "conf.h"
#include "compress.h"
void zlib_compress_config_t::reset()
{
memset(this, 0, sizeof(*this));
mem_level.reset();
window_bits.reset();
strategy.reset();
}
#if !defined(WITH_ZLIB)
extern int compress_zlib_dummy;
int compress_zlib_dummy = 0;
@ -61,24 +73,64 @@ int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
{
assert(method == M_DEFLATE);
assert(level > 0); assert(cresult != NULL);
UNUSED(cb_parm);
int r = UPX_E_ERROR;
int zr;
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : NULL;
zlib_compress_result_t *res = &cresult->result_zlib;
if (level == 10)
level = 9;
zlib_compress_config_t::mem_level_t mem_level;
zlib_compress_config_t::window_bits_t window_bits;
zlib_compress_config_t::strategy_t strategy;
// cconf overrides
if (lcconf)
{
oassign(mem_level, lcconf->mem_level);
oassign(window_bits, lcconf->window_bits);
oassign(strategy, lcconf->strategy);
}
res->dummy = 0;
z_stream s;
s.zalloc = (alloc_func) 0;
s.zfree = (free_func) 0;
s.next_in = (Bytef*) (acc_uintptr_t) src; // UNCONST
s.next_in = const_cast<upx_bytep>(src); // UNCONST
s.avail_in = src_len;
s.next_out = dst;
s.avail_out = *dst_len;
s.total_in = s.total_out = 0;
UNUSED(src); UNUSED(src_len);
UNUSED(dst); UNUSED(dst_len);
UNUSED(cb_parm);
UNUSED(method); UNUSED(level);
UNUSED(cconf_parm);
UNUSED(cresult);
return UPX_E_ERROR;
zr = deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
mem_level, strategy);
if (zr != Z_OK)
goto error;
zr = deflate(&s, Z_FINISH);
if (zr != Z_STREAM_END)
goto error;
zr = deflateEnd(&s);
if (zr != Z_OK)
goto error;
r = UPX_E_OK;
goto done;
error:
(void) deflateEnd(&s);
r = convert_errno_from_zlib(zr);
if (r == UPX_E_OK)
r = UPX_E_ERROR;
done:
if (r == UPX_E_OK)
{
if (s.avail_in != 0 || s.total_in != src_len)
r = UPX_E_ERROR;
}
assert(s.total_in <= src_len);
assert(s.total_out <= *dst_len);
*dst_len = s.total_out;
return r;
}
@ -136,7 +188,7 @@ done:
/*************************************************************************
//
// test_overlap
**************************************************************************/
int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
@ -145,13 +197,18 @@ int upx_zlib_test_overlap ( const upx_bytep buf, unsigned src_off,
const upx_compress_result_t *cresult )
{
assert(method == M_DEFLATE);
UNUSED(cresult);
UNUSED(buf); UNUSED(src_off);
UNUSED(src_len); UNUSED(dst_len);
UNUSED(method);
UNUSED(cresult);
// FIXME - implement this
// Note that Packer::verifyOverlappingDecompression() will
// verify the final result in any case.
UNUSED(buf);
unsigned overlap_overhead = src_off + src_len - *dst_len;
//printf("upx_zlib_test_overlap: %d\n", overlap_overhead);
if ((int)overlap_overhead >= 256)
return UPX_E_OK;
UNUSED(cresult);
return UPX_E_ERROR;
}

View File

@ -555,11 +555,26 @@ struct ucl_compress_config_t : public REAL_ucl_compress_config_t
};
struct zlib_compress_config_t
{
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
mem_level_t mem_level; // ml
window_bits_t window_bits; // wb
strategy_t strategy; // st
void reset();
};
struct upx_compress_config_t
{
lzma_compress_config_t conf_lzma;
ucl_compress_config_t conf_ucl;
void reset() { conf_lzma.reset(); conf_ucl.reset(); }
zlib_compress_config_t conf_zlib;
void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); }
};
@ -590,6 +605,14 @@ struct ucl_compress_result_t
};
struct zlib_compress_result_t
{
unsigned dummy;
void reset() { memset(this, 0, sizeof(*this)); }
};
struct upx_compress_result_t
{
// debug
@ -598,10 +621,11 @@ struct upx_compress_result_t
lzma_compress_result_t result_lzma;
ucl_compress_result_t result_ucl;
zlib_compress_result_t result_zlib;
void reset() {
memset(this, 0, sizeof(*this));
result_lzma.reset(); result_ucl.reset();
result_lzma.reset(); result_ucl.reset(); result_zlib.reset();
}
};

View File

@ -680,6 +680,15 @@ static int do_option(int optc, const char *arg)
case 816:
getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg);
break;
case 821:
getoptvar(&opt->crp.crp_zlib.mem_level, arg);
break;
case 822:
getoptvar(&opt->crp.crp_zlib.window_bits, arg);
break;
case 823:
getoptvar(&opt->crp.crp_zlib.strategy, arg);
break;
// backup
case 'k':
opt->backup = 1;
@ -932,6 +941,9 @@ static const struct mfx_option longopts[] =
{"crp-lzma-lc", 0x31, 0, 813},
{"crp-lzma-ds", 0x31, 0, 814},
{"crp-lzma-fb", 0x31, 0, 816},
{"crp-zlib-ml", 0x31, 0, 821},
{"crp-zlib-wb", 0x31, 0, 822},
{"crp-zlib-st", 0x31, 0, 823},
// [deprecated - only for compatibility with UPX 2.0x]
{"crp-ms", 0x31, 0, 807},

View File

@ -87,7 +87,8 @@ struct options_t {
struct crp_t {
lzma_compress_config_t crp_lzma;
ucl_compress_config_t crp_ucl;
void reset() { crp_lzma.reset(); crp_ucl.reset(); }
zlib_compress_config_t crp_zlib;
void reset() { crp_lzma.reset(); crp_ucl.reset(); crp_zlib.reset(); }
};
crp_t crp;

View File

@ -217,6 +217,12 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
oassign(cconf.conf_lzma.dict_size, opt->crp.crp_lzma.dict_size);
oassign(cconf.conf_lzma.num_fast_bytes, opt->crp.crp_lzma.num_fast_bytes);
}
if (M_IS_DEFLATE(ph.method))
{
oassign(cconf.conf_zlib.mem_level, opt->crp.crp_zlib.mem_level);
oassign(cconf.conf_zlib.window_bits, opt->crp.crp_zlib.window_bits);
oassign(cconf.conf_zlib.strategy, opt->crp.crp_zlib.strategy);
}
if (uip->ui_pass >= 0)
uip->ui_pass++;
uip->startCallback(ph.u_len, step, uip->ui_pass, uip->ui_total_passes);