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)
|
#if defined(WITH_ZLIB)
|
||||||
const char *upx_zlib_version_string(void);
|
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,
|
int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_bytep dst, unsigned* dst_len,
|
||||||
int method,
|
int method,
|
||||||
const upx_compress_result_t *cresult );
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +28,18 @@
|
|||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.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)
|
#if !defined(WITH_ZLIB)
|
||||||
extern int compress_zlib_dummy;
|
extern int compress_zlib_dummy;
|
||||||
int compress_zlib_dummy = 0;
|
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(method == M_DEFLATE);
|
||||||
assert(level > 0); assert(cresult != NULL);
|
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;
|
z_stream s;
|
||||||
s.zalloc = (alloc_func) 0;
|
s.zalloc = (alloc_func) 0;
|
||||||
s.zfree = (free_func) 0;
|
s.zfree = (free_func) 0;
|
||||||
|
s.next_in = const_cast<upx_bytep>(src); // UNCONST
|
||||||
s.next_in = (Bytef*) (acc_uintptr_t) src; // UNCONST
|
|
||||||
s.avail_in = src_len;
|
s.avail_in = src_len;
|
||||||
s.next_out = dst;
|
s.next_out = dst;
|
||||||
s.avail_out = *dst_len;
|
s.avail_out = *dst_len;
|
||||||
|
s.total_in = s.total_out = 0;
|
||||||
|
|
||||||
UNUSED(src); UNUSED(src_len);
|
zr = deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
|
||||||
UNUSED(dst); UNUSED(dst_len);
|
mem_level, strategy);
|
||||||
UNUSED(cb_parm);
|
if (zr != Z_OK)
|
||||||
UNUSED(method); UNUSED(level);
|
goto error;
|
||||||
UNUSED(cconf_parm);
|
zr = deflate(&s, Z_FINISH);
|
||||||
UNUSED(cresult);
|
if (zr != Z_STREAM_END)
|
||||||
|
goto error;
|
||||||
return UPX_E_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,
|
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 )
|
const upx_compress_result_t *cresult )
|
||||||
{
|
{
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
UNUSED(cresult);
|
|
||||||
|
|
||||||
UNUSED(buf); UNUSED(src_off);
|
// FIXME - implement this
|
||||||
UNUSED(src_len); UNUSED(dst_len);
|
// Note that Packer::verifyOverlappingDecompression() will
|
||||||
UNUSED(method);
|
// verify the final result in any case.
|
||||||
UNUSED(cresult);
|
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;
|
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
|
struct upx_compress_config_t
|
||||||
{
|
{
|
||||||
lzma_compress_config_t conf_lzma;
|
lzma_compress_config_t conf_lzma;
|
||||||
ucl_compress_config_t conf_ucl;
|
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
|
struct upx_compress_result_t
|
||||||
{
|
{
|
||||||
// debug
|
// debug
|
||||||
@ -598,10 +621,11 @@ struct upx_compress_result_t
|
|||||||
|
|
||||||
lzma_compress_result_t result_lzma;
|
lzma_compress_result_t result_lzma;
|
||||||
ucl_compress_result_t result_ucl;
|
ucl_compress_result_t result_ucl;
|
||||||
|
zlib_compress_result_t result_zlib;
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
memset(this, 0, sizeof(*this));
|
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:
|
case 816:
|
||||||
getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg);
|
getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg);
|
||||||
break;
|
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
|
// backup
|
||||||
case 'k':
|
case 'k':
|
||||||
opt->backup = 1;
|
opt->backup = 1;
|
||||||
@ -932,6 +941,9 @@ static const struct mfx_option longopts[] =
|
|||||||
{"crp-lzma-lc", 0x31, 0, 813},
|
{"crp-lzma-lc", 0x31, 0, 813},
|
||||||
{"crp-lzma-ds", 0x31, 0, 814},
|
{"crp-lzma-ds", 0x31, 0, 814},
|
||||||
{"crp-lzma-fb", 0x31, 0, 816},
|
{"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]
|
// [deprecated - only for compatibility with UPX 2.0x]
|
||||||
{"crp-ms", 0x31, 0, 807},
|
{"crp-ms", 0x31, 0, 807},
|
||||||
|
|
||||||
|
@ -87,7 +87,8 @@ struct options_t {
|
|||||||
struct crp_t {
|
struct crp_t {
|
||||||
lzma_compress_config_t crp_lzma;
|
lzma_compress_config_t crp_lzma;
|
||||||
ucl_compress_config_t crp_ucl;
|
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;
|
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.dict_size, opt->crp.crp_lzma.dict_size);
|
||||||
oassign(cconf.conf_lzma.num_fast_bytes, opt->crp.crp_lzma.num_fast_bytes);
|
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)
|
if (uip->ui_pass >= 0)
|
||||||
uip->ui_pass++;
|
uip->ui_pass++;
|
||||||
uip->startCallback(ph.u_len, step, uip->ui_pass, uip->ui_total_passes);
|
uip->startCallback(ph.u_len, step, uip->ui_pass, uip->ui_total_passes);
|
||||||
|
Reference in New Issue
Block a user