From f383629282e88d52511c54dbdbc83b7a02f3793b Mon Sep 17 00:00:00 2001 From: John Reiser Date: Thu, 12 Jul 2012 07:04:56 -0700 Subject: [PATCH] compressWithFilters(..., inhibit_compression_check=0) // SourceForge bug 3541020 Not good to check compression ratio on every block when blocksize < file_size, as when --force_execve of Elf > 0x80000 bytes. --- src/p_unix.cpp | 4 +++- src/packer.cpp | 31 +++++++++++++++++++------------ src/packer.h | 9 ++++++--- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/p_unix.cpp b/src/p_unix.cpp index 5f61caa8..8c9d1bd8 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -142,6 +142,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft) // ui_total_passes = 0; unsigned remaining = file_size; + unsigned n_block = 0; while (remaining > 0) { // FIXME: disable filters if we have more than one block. @@ -170,7 +171,8 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft) // that is, AFTER filtering. We want BEFORE filtering, // so that decompression checks the end-to-end checksum. unsigned const end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler); - compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy); + compressWithFilters(&ft, OVERHEAD, NULL_cconf, filter_strategy, + !!n_block++); // check compression ratio only on first block if (ph.c_len < ph.u_len) { const upx_bytep tbuf = NULL; diff --git a/src/packer.cpp b/src/packer.cpp index 4dff9b7b..28ac6f69 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -1311,7 +1311,8 @@ void Packer::compressWithFilters(upx_bytep i_ptr, unsigned i_len, Filter *parm_ft, const unsigned overlap_range, const upx_compress_config_t *cconf, - int filter_strategy) + int filter_strategy, + int inhibit_compression_check) { parm_ft->buf_len = f_len; // struct copies @@ -1487,14 +1488,17 @@ void Packer::compressWithFilters(upx_bytep i_ptr, unsigned i_len, this->ph = best_ph; *parm_ft = best_ft; - // finally check compression ratio - if (best_ph.c_len + best_ph_lsize >= best_ph.u_len) - throwNotCompressible(); - if (!checkCompressionRatio(best_ph.u_len, best_ph.c_len)) - throwNotCompressible(); + // Finally, check compression ratio. + // Might be inhibited when blocksize < file_size, for instance. + if (!inhibit_compression_check) { + if (best_ph.c_len + best_ph_lsize >= best_ph.u_len) + throwNotCompressible(); + if (!checkCompressionRatio(best_ph.u_len, best_ph.c_len)) + throwNotCompressible(); - // postconditions 2) - assert(best_ph.overlap_overhead > 0); + // postconditions 2) + assert(best_ph.overlap_overhead > 0); + } // convenience buildLoader(&best_ft); @@ -1508,10 +1512,11 @@ void Packer::compressWithFilters(upx_bytep i_ptr, unsigned i_len, void Packer::compressWithFilters(Filter *ft, const unsigned overlap_range, const upx_compress_config_t *cconf, - int filter_strategy) + int filter_strategy, + int inhibit_compression_check) { compressWithFilters(ft, overlap_range, cconf, filter_strategy, - 0, 0, 0, NULL, 0); + 0, 0, 0, NULL, 0, inhibit_compression_check); } @@ -1522,7 +1527,8 @@ void Packer::compressWithFilters(Filter *ft, unsigned filter_off, unsigned ibuf_off, unsigned obuf_off, - const upx_bytep hdr_ptr, unsigned hdr_len) + const upx_bytep hdr_ptr, unsigned hdr_len, + int inhibit_compression_check) { ibuf.checkState(); obuf.checkState(); @@ -1538,7 +1544,8 @@ void Packer::compressWithFilters(Filter *ft, o_ptr, f_ptr, f_len, hdr_ptr, hdr_len, - ft, overlap_range, cconf, filter_strategy); + ft, overlap_range, cconf, filter_strategy, + inhibit_compression_check); ibuf.checkState(); obuf.checkState(); } diff --git a/src/packer.h b/src/packer.h index 3f9585d4..e31eb468 100644 --- a/src/packer.h +++ b/src/packer.h @@ -181,7 +181,8 @@ protected: void compressWithFilters(Filter *ft, const unsigned overlap_range, const upx_compress_config_t *cconf, - int filter_strategy = 0); + int filter_strategy = 0, + int inhibit_compression_check = 0); void compressWithFilters(Filter *ft, const unsigned overlap_range, const upx_compress_config_t *cconf, @@ -189,7 +190,8 @@ protected: unsigned filter_buf_off, unsigned compress_ibuf_off, unsigned compress_obuf_off, - const upx_bytep hdr_ptr, unsigned hdr_len); + const upx_bytep hdr_ptr, unsigned hdr_len, + int inhibit_compression_check = 0); // real compression driver void compressWithFilters(upx_bytep i_ptr, unsigned i_len, upx_bytep o_ptr, @@ -198,7 +200,8 @@ protected: Filter *ft, const unsigned overlap_range, const upx_compress_config_t *cconf, - int filter_strategy); + int filter_strategy, + int inhibit_compression_check = 0); // util for verifying overlapping decompresion // non-destructive test