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:
@ -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
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
28
src/conf.h
28
src/conf.h
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
12
src/main.cpp
12
src/main.cpp
@ -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},
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user