src: clang-format compress_*.cpp; minor cleanup
This commit is contained in:
@@ -74,6 +74,7 @@ endif
|
|||||||
# automatically format some C++ source code files
|
# automatically format some C++ source code files
|
||||||
ifeq ($(shell uname),Linux)
|
ifeq ($(shell uname),Linux)
|
||||||
CLANG_FORMAT_FILES += bele.h bele_policy.h
|
CLANG_FORMAT_FILES += bele.h bele_policy.h
|
||||||
|
CLANG_FORMAT_FILES += compress_lzma.cpp compress_ucl.cpp compress_zlib.cpp
|
||||||
CLANG_FORMAT_FILES += except.cpp except.h
|
CLANG_FORMAT_FILES += except.cpp except.h
|
||||||
CLANG_FORMAT_FILES += file.cpp file.h
|
CLANG_FORMAT_FILES += file.cpp file.h
|
||||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
||||||
|
|||||||
+116
-126
@@ -25,27 +25,24 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "util/membuffer.h"
|
#include "util/membuffer.h"
|
||||||
|
|
||||||
#if (ACC_CC_CLANG)
|
#if (ACC_CC_CLANG)
|
||||||
# pragma clang diagnostic ignored "-Wshadow"
|
#pragma clang diagnostic ignored "-Wshadow"
|
||||||
#endif
|
#endif
|
||||||
#if (ACC_CC_GNUC >= 0x040200)
|
#if (ACC_CC_GNUC >= 0x040200)
|
||||||
# pragma GCC diagnostic ignored "-Wshadow"
|
#pragma GCC diagnostic ignored "-Wshadow"
|
||||||
#endif
|
#endif
|
||||||
#if (ACC_CC_MSC)
|
#if (ACC_CC_MSC)
|
||||||
# pragma warning(disable: 4456) // -Wno-shadow
|
#pragma warning(disable : 4456) // -Wno-shadow
|
||||||
#endif
|
#endif
|
||||||
#if (ACC_CC_MSC && (_MSC_VER < 1900))
|
#if (ACC_CC_MSC && (_MSC_VER < 1900))
|
||||||
# pragma warning(disable: 4127) // warning C4127: conditional expression is constant
|
#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void lzma_compress_config_t::reset() {
|
||||||
void lzma_compress_config_t::reset()
|
|
||||||
{
|
|
||||||
pos_bits.reset();
|
pos_bits.reset();
|
||||||
lit_pos_bits.reset();
|
lit_pos_bits.reset();
|
||||||
lit_context_bits.reset();
|
lit_context_bits.reset();
|
||||||
@@ -57,7 +54,6 @@ void lzma_compress_config_t::reset()
|
|||||||
max_num_probs = 0;
|
max_num_probs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// INFO: the LZMA SDK is covered by a permissive license which allows
|
// INFO: the LZMA SDK is covered by a permissive license which allows
|
||||||
// using unmodified LZMA source code in UPX and the UPX stubs.
|
// using unmodified LZMA source code in UPX and the UPX stubs.
|
||||||
// See SPECIAL EXCEPTION below.
|
// See SPECIAL EXCEPTION below.
|
||||||
@@ -94,21 +90,18 @@ void lzma_compress_config_t::reset()
|
|||||||
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
||||||
// while you keep LZMA SDK code unmodified.
|
// while you keep LZMA SDK code unmodified.
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress defaults
|
// compress defaults
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int prepare(lzma_compress_result_t *res,
|
static bool prepare_result(lzma_compress_result_t *res, unsigned src_len, int method, int level,
|
||||||
unsigned src_len, int method, int level,
|
const lzma_compress_config_t *lcconf) {
|
||||||
const lzma_compress_config_t *lcconf)
|
|
||||||
{
|
|
||||||
// setup defaults
|
// setup defaults
|
||||||
res->pos_bits = 2; // 0 .. 4
|
res->pos_bits = 2; // 0 .. 4
|
||||||
res->lit_pos_bits = 0; // 0 .. 4
|
res->lit_pos_bits = 0; // 0 .. 4
|
||||||
res->lit_context_bits = 3; // 0 .. 8
|
res->lit_context_bits = 3; // 0 .. 8
|
||||||
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
|
res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30
|
||||||
res->fast_mode = 2;
|
res->fast_mode = 2; // 0 .. 2
|
||||||
res->num_fast_bytes = 64; // 5 .. 273
|
res->num_fast_bytes = 64; // 5 .. 273
|
||||||
res->match_finder_cycles = 0;
|
res->match_finder_cycles = 0;
|
||||||
// UPX overrides
|
// UPX overrides
|
||||||
@@ -132,8 +125,7 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: tune these settings according to level
|
// TODO: tune these settings according to level
|
||||||
switch (level)
|
switch (level) {
|
||||||
{
|
|
||||||
case 1:
|
case 1:
|
||||||
res->dict_size = 256 * 1024;
|
res->dict_size = 256 * 1024;
|
||||||
res->fast_mode = 0;
|
res->fast_mode = 0;
|
||||||
@@ -166,8 +158,7 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// cconf overrides
|
// cconf overrides
|
||||||
if (lcconf)
|
if (lcconf) {
|
||||||
{
|
|
||||||
oassign(res->pos_bits, lcconf->pos_bits);
|
oassign(res->pos_bits, lcconf->pos_bits);
|
||||||
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
oassign(res->lit_pos_bits, lcconf->lit_pos_bits);
|
||||||
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
oassign(res->lit_context_bits, lcconf->lit_context_bits);
|
||||||
@@ -180,21 +171,16 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
res->dict_size = src_len;
|
res->dict_size = src_len;
|
||||||
|
|
||||||
// limit num_probs
|
// limit num_probs
|
||||||
if (lcconf && lcconf->max_num_probs)
|
if (lcconf && lcconf->max_num_probs) {
|
||||||
{
|
for (;;) {
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
unsigned n = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
||||||
if (n <= lcconf->max_num_probs)
|
if (n <= lcconf->max_num_probs)
|
||||||
break;
|
break;
|
||||||
if (res->lit_pos_bits > res->lit_context_bits)
|
if (res->lit_pos_bits > res->lit_context_bits) {
|
||||||
{
|
|
||||||
if (res->lit_pos_bits == 0)
|
if (res->lit_pos_bits == 0)
|
||||||
goto error;
|
goto error;
|
||||||
res->lit_pos_bits -= 1;
|
res->lit_pos_bits -= 1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if (res->lit_context_bits == 0)
|
if (res->lit_context_bits == 0)
|
||||||
goto error;
|
goto error;
|
||||||
res->lit_context_bits -= 1;
|
res->lit_context_bits -= 1;
|
||||||
@@ -209,14 +195,14 @@ static int prepare(lzma_compress_result_t *res,
|
|||||||
lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes);
|
lzma_compress_config_t::num_fast_bytes_t::assertValue(res->num_fast_bytes);
|
||||||
|
|
||||||
res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
res->num_probs = 1846 + (768u << (res->lit_context_bits + res->lit_pos_bits));
|
||||||
//printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
// printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
|
||||||
return 0;
|
// res->lit_context_bits, res->dict_size, res->num_probs);
|
||||||
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress - cruft because of pseudo-COM layer
|
// compress - cruft because of pseudo-COM layer
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -235,69 +221,80 @@ error:
|
|||||||
|
|
||||||
namespace MyLzma {
|
namespace MyLzma {
|
||||||
|
|
||||||
struct InStream: public ISequentialInStream, public CMyUnknownImp
|
struct InStream : public ISequentialInStream, public CMyUnknownImp {
|
||||||
{
|
virtual ~InStream() {}
|
||||||
virtual ~InStream() { }
|
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
const Byte *b_buf; size_t b_size; size_t b_pos;
|
const Byte *b_buf;
|
||||||
|
size_t b_size;
|
||||||
|
size_t b_pos;
|
||||||
void Init(const Byte *data, size_t size) {
|
void Init(const Byte *data, size_t size) {
|
||||||
b_buf = data; b_size = size; b_pos = 0;
|
b_buf = data;
|
||||||
|
b_size = size;
|
||||||
|
b_pos = 0;
|
||||||
}
|
}
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override;
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize) {
|
||||||
{
|
|
||||||
size_t remain = b_size - b_pos;
|
size_t remain = b_size - b_pos;
|
||||||
if (size > remain) size = (UInt32) remain;
|
if (size > remain)
|
||||||
|
size = (UInt32) remain;
|
||||||
memmove(data, b_buf + b_pos, size);
|
memmove(data, b_buf + b_pos, size);
|
||||||
b_pos += size;
|
b_pos += size;
|
||||||
if (processedSize != nullptr) *processedSize = size;
|
if (processedSize != nullptr)
|
||||||
|
*processedSize = size;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OutStream : public ISequentialOutStream, public CMyUnknownImp
|
struct OutStream : public ISequentialOutStream, public CMyUnknownImp {
|
||||||
{
|
virtual ~OutStream() {}
|
||||||
virtual ~OutStream() { }
|
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
Byte *b_buf; size_t b_size; size_t b_pos; bool overflow;
|
Byte *b_buf;
|
||||||
|
size_t b_size;
|
||||||
|
size_t b_pos;
|
||||||
|
bool overflow;
|
||||||
void Init(Byte *data, size_t size) {
|
void Init(Byte *data, size_t size) {
|
||||||
b_buf = data; b_size = size; b_pos = 0; overflow = false;
|
b_buf = data;
|
||||||
|
b_size = size;
|
||||||
|
b_pos = 0;
|
||||||
|
overflow = false;
|
||||||
}
|
}
|
||||||
HRESULT WriteByte(Byte c) {
|
HRESULT WriteByte(Byte c) {
|
||||||
if (b_pos >= b_size) { overflow = true; return E_FAIL; }
|
if (b_pos >= b_size) {
|
||||||
|
overflow = true;
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
b_buf[b_pos++] = c;
|
b_buf[b_pos++] = c;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override;
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) {
|
||||||
{
|
|
||||||
size_t remain = b_size - b_pos;
|
size_t remain = b_size - b_pos;
|
||||||
if (size > remain) size = (UInt32) remain, overflow = true;
|
if (size > remain)
|
||||||
|
size = (UInt32) remain, overflow = true;
|
||||||
memmove(b_buf + b_pos, data, size);
|
memmove(b_buf + b_pos, data, size);
|
||||||
b_pos += size;
|
b_pos += size;
|
||||||
if (processedSize != nullptr) *processedSize = size;
|
if (processedSize != nullptr)
|
||||||
|
*processedSize = size;
|
||||||
return overflow ? E_FAIL : S_OK;
|
return overflow ? E_FAIL : S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp {
|
||||||
{
|
virtual ~ProgressInfo() {}
|
||||||
virtual ~ProgressInfo() { }
|
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
||||||
upx_callback_p cb;
|
upx_callback_p cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
|
||||||
{
|
|
||||||
if (cb && cb->nprogress)
|
if (cb && cb->nprogress)
|
||||||
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace MyLzma
|
||||||
|
|
||||||
#include <lzma-sdk/C/Common/Alloc.cpp>
|
#include <lzma-sdk/C/Common/Alloc.cpp>
|
||||||
#include <lzma-sdk/C/Common/CRC.cpp>
|
#include <lzma-sdk/C/Common/CRC.cpp>
|
||||||
@@ -311,28 +308,27 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
|
|||||||
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
|
#include <lzma-sdk/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp>
|
||||||
#undef RC_NORMALIZE
|
#undef RC_NORMALIZE
|
||||||
|
|
||||||
|
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
upx_callback_p cb, int method, int level,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
upx_callback_p cb,
|
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf_parm,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
assert(level > 0); assert(cresult != nullptr);
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
HRESULT rh;
|
HRESULT rh;
|
||||||
const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
||||||
lzma_compress_result_t *res = &cresult->result_lzma;
|
lzma_compress_result_t *const res = &cresult->result_lzma;
|
||||||
|
|
||||||
MyLzma::InStream is; is.AddRef();
|
MyLzma::InStream is;
|
||||||
MyLzma::OutStream os; os.AddRef();
|
is.AddRef();
|
||||||
|
MyLzma::OutStream os;
|
||||||
|
os.AddRef();
|
||||||
is.Init(src, src_len);
|
is.Init(src, src_len);
|
||||||
os.Init(dst, *dst_len);
|
os.Init(dst, *dst_len);
|
||||||
|
|
||||||
MyLzma::ProgressInfo progress; progress.AddRef();
|
MyLzma::ProgressInfo progress;
|
||||||
|
progress.AddRef();
|
||||||
progress.cb = cb;
|
progress.cb = cb;
|
||||||
|
|
||||||
NCompress::NLZMA::CEncoder enc;
|
NCompress::NLZMA::CEncoder enc;
|
||||||
@@ -348,13 +344,10 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
};
|
};
|
||||||
PROPVARIANT pr[8];
|
PROPVARIANT pr[8];
|
||||||
const unsigned nprops = 8;
|
const unsigned nprops = 8;
|
||||||
static const wchar_t matchfinder[] = L"BT4";
|
if (!prepare_result(res, src_len, method, level, lcconf))
|
||||||
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
|
||||||
pr[7].vt = VT_BSTR; pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
|
|
||||||
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4;
|
|
||||||
pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
|
|
||||||
if (prepare(res, src_len, method, level, lcconf) != 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
|
pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4;
|
||||||
|
pr[7].vt = VT_BSTR;
|
||||||
pr[0].uintVal = res->pos_bits;
|
pr[0].uintVal = res->pos_bits;
|
||||||
pr[1].uintVal = res->lit_pos_bits;
|
pr[1].uintVal = res->lit_pos_bits;
|
||||||
pr[2].uintVal = res->lit_context_bits;
|
pr[2].uintVal = res->lit_context_bits;
|
||||||
@@ -362,25 +355,31 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
pr[4].uintVal = res->fast_mode;
|
pr[4].uintVal = res->fast_mode;
|
||||||
pr[5].uintVal = res->num_fast_bytes;
|
pr[5].uintVal = res->num_fast_bytes;
|
||||||
pr[6].uintVal = res->match_finder_cycles;
|
pr[6].uintVal = res->match_finder_cycles;
|
||||||
|
static const wchar_t matchfinder[] = L"BT4";
|
||||||
|
assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0);
|
||||||
|
pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK)
|
if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK)
|
||||||
goto error;
|
goto error;
|
||||||
|
// encode properties in LZMA-style (5 bytes)
|
||||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||||
goto error;
|
goto error;
|
||||||
if (os.overflow) {
|
if (os.overflow) {
|
||||||
//r = UPX_E_OUTPUT_OVERRUN;
|
// r = UPX_E_OUTPUT_OVERRUN;
|
||||||
r = UPX_E_NOT_COMPRESSIBLE;
|
r = UPX_E_NOT_COMPRESSIBLE;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
assert(os.b_pos == 5);
|
assert(os.b_pos == 5);
|
||||||
|
|
||||||
|
// reset and encode properties in UPX-style (2 bytes)
|
||||||
os.b_pos = 0;
|
os.b_pos = 0;
|
||||||
// extra stuff in first byte: 5 high bits convenience for stub decompressor
|
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||||
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||||
os.WriteByte(Byte((t << 3) | res->pos_bits));
|
os.WriteByte(Byte((t << 3) | res->pos_bits));
|
||||||
os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits)));
|
os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits)));
|
||||||
|
|
||||||
|
// compress
|
||||||
rh = enc.Code(&is, &os, nullptr, nullptr, &progress);
|
rh = enc.Code(&is, &os, nullptr, nullptr, &progress);
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -391,26 +390,24 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
assert(os.b_pos <= *dst_len);
|
assert(os.b_pos <= *dst_len);
|
||||||
if (rh == E_OUTOFMEMORY)
|
if (rh == E_OUTOFMEMORY)
|
||||||
r = UPX_E_OUT_OF_MEMORY;
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
else if (os.overflow)
|
else if (os.overflow) {
|
||||||
{
|
|
||||||
assert(os.b_pos == *dst_len);
|
assert(os.b_pos == *dst_len);
|
||||||
//r = UPX_E_OUTPUT_OVERRUN;
|
// r = UPX_E_OUTPUT_OVERRUN;
|
||||||
r = UPX_E_NOT_COMPRESSIBLE;
|
r = UPX_E_NOT_COMPRESSIBLE;
|
||||||
}
|
} else if (rh == S_OK) {
|
||||||
else if (rh == S_OK)
|
|
||||||
{
|
|
||||||
assert(is.b_pos == src_len);
|
assert(is.b_pos == src_len);
|
||||||
r = UPX_E_OK;
|
r = UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
*dst_len = (unsigned) os.b_pos;
|
*dst_len = (unsigned) os.b_pos;
|
||||||
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
|
// printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits,
|
||||||
//printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
// res->lit_pos_bits,
|
||||||
|
// res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
|
||||||
|
// printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// decompress
|
// decompress
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -422,22 +419,21 @@ error:
|
|||||||
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h>
|
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.h>
|
||||||
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c>
|
#include <lzma-sdk/C/7zip/Compress/LZMA_C/LzmaDecode.c>
|
||||||
|
|
||||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_lzma_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
int method, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
// see res->num_probs above
|
// see res->num_probs above
|
||||||
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||||
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||||
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||||
|
|
||||||
CLzmaDecoderState s; memset(&s, 0, sizeof(s));
|
CLzmaDecoderState s;
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
SizeT src_out = 0, dst_out = 0;
|
SizeT src_out = 0, dst_out = 0;
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
int rh;
|
int rh;
|
||||||
|
|
||||||
|
// decode UPX-style properties (2 bytes)
|
||||||
if (src_len < 3) {
|
if (src_len < 3) {
|
||||||
r = UPX_E_INPUT_OVERRUN;
|
r = UPX_E_INPUT_OVERRUN;
|
||||||
goto error;
|
goto error;
|
||||||
@@ -445,27 +441,31 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
s.Properties.pb = src[0] & 7;
|
s.Properties.pb = src[0] & 7;
|
||||||
s.Properties.lp = (src[1] >> 4);
|
s.Properties.lp = (src[1] >> 4);
|
||||||
s.Properties.lc = src[1] & 15;
|
s.Properties.lc = src[1] & 15;
|
||||||
if (s.Properties.pb >= 5) goto error;
|
if (s.Properties.pb >= 5)
|
||||||
if (s.Properties.lp >= 5) goto error;
|
goto error;
|
||||||
if (s.Properties.lc >= 9) goto error;
|
if (s.Properties.lp >= 5)
|
||||||
// extra
|
goto error;
|
||||||
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error;
|
if (s.Properties.lc >= 9)
|
||||||
src += 2; src_len -= 2;
|
goto error;
|
||||||
|
// UPX extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||||
|
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp)
|
||||||
|
goto error;
|
||||||
|
src += 2;
|
||||||
|
src_len -= 2;
|
||||||
|
|
||||||
if (cresult)
|
if (cresult) {
|
||||||
{
|
|
||||||
assert(cresult->method == method);
|
assert(cresult->method == method);
|
||||||
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
||||||
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
||||||
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||||
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||||
const lzma_compress_result_t *res = &cresult->result_lzma;
|
const lzma_compress_result_t *res = &cresult->result_lzma;
|
||||||
|
// printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits,
|
||||||
|
// res->lit_context_bits, res->dict_size, res->num_probs);
|
||||||
UNUSED(res);
|
UNUSED(res);
|
||||||
//printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs);
|
|
||||||
}
|
}
|
||||||
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||||
if (!s.Probs)
|
if (!s.Probs) {
|
||||||
{
|
|
||||||
r = UPX_E_OUT_OF_MEMORY;
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -476,8 +476,7 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
r = UPX_E_OK;
|
r = UPX_E_OK;
|
||||||
if (src_out != src_len)
|
if (src_out != src_len)
|
||||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
}
|
} else if (rh == LZMA_RESULT_INPUT_OVERRUN)
|
||||||
else if (rh == LZMA_RESULT_INPUT_OVERRUN)
|
|
||||||
r = UPX_E_INPUT_OVERRUN;
|
r = UPX_E_INPUT_OVERRUN;
|
||||||
else if (rh == LZMA_RESULT_OUTPUT_OVERRUN)
|
else if (rh == LZMA_RESULT_OUTPUT_OVERRUN)
|
||||||
r = UPX_E_OUTPUT_OVERRUN;
|
r = UPX_E_OUTPUT_OVERRUN;
|
||||||
@@ -488,24 +487,20 @@ error:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// test_overlap - see <ucl/ucl.h> for semantics
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_lzma_test_overlap ( const upx_bytep buf,
|
int upx_lzma_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
const upx_bytep tbuf,
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
unsigned src_off, unsigned src_len,
|
const upx_compress_result_t *cresult) {
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
|
|
||||||
MemBuffer b(src_off + src_len);
|
MemBuffer b(src_off + src_len);
|
||||||
memcpy(b + src_off, buf + src_off, src_len);
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
unsigned saved_dst_len = *dst_len;
|
unsigned saved_dst_len = *dst_len;
|
||||||
int r = upx_lzma_decompress(raw_index_bytes(b, src_off, src_len), src_len, raw_bytes(b, *dst_len), dst_len, method, cresult);
|
int r = upx_lzma_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||||
|
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||||
if (r != UPX_E_OK)
|
if (r != UPX_E_OK)
|
||||||
return r;
|
return r;
|
||||||
if (*dst_len != saved_dst_len)
|
if (*dst_len != saved_dst_len)
|
||||||
@@ -518,22 +513,17 @@ int upx_lzma_test_overlap ( const upx_bytep buf,
|
|||||||
return UPX_E_OK;
|
return UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc
|
// misc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_lzma_init(void)
|
int upx_lzma_init(void) { return 0; }
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *upx_lzma_version_string(void)
|
const char *upx_lzma_version_string(void) {
|
||||||
{
|
|
||||||
#if (WITH_LZMA == 0x443)
|
#if (WITH_LZMA == 0x443)
|
||||||
return "4.43";
|
return "4.43";
|
||||||
#else
|
#else
|
||||||
# error "unknown WITH_LZMA version"
|
#error "unknown WITH_LZMA version"
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -549,7 +539,7 @@ TEST_CASE("upx_lzma_decompress") {
|
|||||||
unsigned d_len;
|
unsigned d_len;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
c_data = (C*) "\x1a\x03\x00\x7f\xed\x3c\x00\x00\x00";
|
c_data = (C *) "\x1a\x03\x00\x7f\xed\x3c\x00\x00\x00";
|
||||||
d_len = 16;
|
d_len = 16;
|
||||||
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
||||||
CHECK((r == 0 && d_len == 16));
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
|||||||
+101
-114
@@ -25,60 +25,62 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
static int convert_errno_from_ucl(int r)
|
static int convert_errno_from_ucl(int r) {
|
||||||
{
|
switch (r) {
|
||||||
switch (r)
|
case UCL_E_OK:
|
||||||
{
|
return UPX_E_OK;
|
||||||
case UCL_E_OK: return UPX_E_OK;
|
case UCL_E_ERROR:
|
||||||
case UCL_E_ERROR: return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
case UCL_E_OUT_OF_MEMORY: return UPX_E_OUT_OF_MEMORY;
|
case UCL_E_OUT_OF_MEMORY:
|
||||||
case UCL_E_NOT_COMPRESSIBLE: return UPX_E_NOT_COMPRESSIBLE;
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
case UCL_E_INPUT_OVERRUN: return UPX_E_INPUT_OVERRUN;
|
case UCL_E_NOT_COMPRESSIBLE:
|
||||||
case UCL_E_OUTPUT_OVERRUN: return UPX_E_OUTPUT_OVERRUN;
|
return UPX_E_NOT_COMPRESSIBLE;
|
||||||
case UCL_E_LOOKBEHIND_OVERRUN: return UPX_E_LOOKBEHIND_OVERRUN;
|
case UCL_E_INPUT_OVERRUN:
|
||||||
case UCL_E_EOF_NOT_FOUND: return UPX_E_EOF_NOT_FOUND;
|
return UPX_E_INPUT_OVERRUN;
|
||||||
case UCL_E_INPUT_NOT_CONSUMED: return UPX_E_INPUT_NOT_CONSUMED;
|
case UCL_E_OUTPUT_OVERRUN:
|
||||||
// case UCL_E_NOT_YET_IMPLEMENTED: return UPX_E_NOT_YET_IMPLEMENTED;
|
return UPX_E_OUTPUT_OVERRUN;
|
||||||
case UCL_E_INVALID_ARGUMENT: return UPX_E_INVALID_ARGUMENT;
|
case UCL_E_LOOKBEHIND_OVERRUN:
|
||||||
|
return UPX_E_LOOKBEHIND_OVERRUN;
|
||||||
|
case UCL_E_EOF_NOT_FOUND:
|
||||||
|
return UPX_E_EOF_NOT_FOUND;
|
||||||
|
case UCL_E_INPUT_NOT_CONSUMED:
|
||||||
|
return UPX_E_INPUT_NOT_CONSUMED;
|
||||||
|
case UCL_E_INVALID_ARGUMENT:
|
||||||
|
return UPX_E_INVALID_ARGUMENT;
|
||||||
// UCL extra:
|
// UCL extra:
|
||||||
case UCL_E_OVERLAP_OVERRUN: return UPX_E_ERROR;
|
case UCL_E_OVERLAP_OVERRUN:
|
||||||
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
|
||||||
{
|
if (state != -1 && state != 3)
|
||||||
if (state != -1 && state != 3) return;
|
return;
|
||||||
upx_callback_p cb = (upx_callback_p) user;
|
upx_callback_p cb = (upx_callback_p) user;
|
||||||
if (cb && cb->nprogress)
|
if (cb && cb->nprogress)
|
||||||
cb->nprogress(cb, a, b);
|
cb->nprogress(cb, a, b);
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_callback_p cb_parm, int method, int level,
|
||||||
upx_callback_p cb_parm,
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf_parm,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r;
|
int r;
|
||||||
assert(level > 0); assert(cresult != nullptr);
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
|
||||||
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
COMPILE_TIME_ASSERT(sizeof(ucl_compress_config_t) == sizeof(REAL_ucl_compress_config_t))
|
||||||
|
|
||||||
@@ -90,49 +92,47 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
cb.user = cb_parm;
|
cb.user = cb_parm;
|
||||||
}
|
}
|
||||||
|
|
||||||
ucl_compress_config_t cconf; cconf.reset();
|
ucl_compress_config_t cconf;
|
||||||
if (cconf_parm)
|
cconf.reset();
|
||||||
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf)); // cconf = cconf_parm->conf_ucl; // struct copy
|
if (cconf_parm) {
|
||||||
|
// cconf = cconf_parm->conf_ucl; // struct copy
|
||||||
|
memcpy(&cconf, &cconf_parm->conf_ucl, sizeof(cconf));
|
||||||
|
}
|
||||||
|
|
||||||
ucl_uint *res = cresult->result_ucl.result;
|
ucl_uint *const res = cresult->result_ucl.result;
|
||||||
// assume no info available - fill in worst case results
|
// assume no info available - fill in worst case results
|
||||||
//res[0] = 1; // min_offset_found - NOT USED
|
// res[0] = 1; // min_offset_found - NOT USED
|
||||||
res[1] = src_len - 1; // max_offset_found
|
res[1] = src_len - 1; // max_offset_found
|
||||||
//res[2] = 2; // min_match_found - NOT USED
|
// res[2] = 2; // min_match_found - NOT USED
|
||||||
res[3] = src_len - 1; // max_match_found
|
res[3] = src_len - 1; // max_match_found
|
||||||
//res[4] = 1; // min_run_found - NOT USED
|
// res[4] = 1; // min_run_found - NOT USED
|
||||||
res[5] = src_len; // max_run_found
|
res[5] = src_len; // max_run_found
|
||||||
res[6] = 1; // first_offset_found
|
res[6] = 1; // first_offset_found
|
||||||
//res[7] = 999999; // same_match_offsets_found - NOT USED
|
// res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||||
|
|
||||||
// prepare bit-buffer settings
|
// prepare bit-buffer settings
|
||||||
cconf.bb_endian = 0;
|
cconf.bb_endian = 0;
|
||||||
cconf.bb_size = 0;
|
cconf.bb_size = 0;
|
||||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) {
|
||||||
{
|
|
||||||
static const unsigned char sizes[3] = {32, 8, 16};
|
static const unsigned char sizes[3] = {32, 8, 16};
|
||||||
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// optimize compression parms
|
// optimize compression parms
|
||||||
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
cconf.max_offset = 8*1024-1;
|
cconf.max_offset = 8 * 1024 - 1;
|
||||||
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||||
cconf.max_offset = 32*1024-1;
|
cconf.max_offset = 32 * 1024 - 1;
|
||||||
|
|
||||||
if M_IS_NRV2B(method)
|
if M_IS_NRV2B (method)
|
||||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
&cb, level, &cconf, res);
|
else if M_IS_NRV2D (method)
|
||||||
else if M_IS_NRV2D(method)
|
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
else if M_IS_NRV2E (method)
|
||||||
&cb, level, &cconf, res);
|
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len, &cb, level, &cconf, res);
|
||||||
else if M_IS_NRV2E(method)
|
|
||||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
|
||||||
&cb, level, &cconf, res);
|
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method");
|
||||||
return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
@@ -145,46 +145,41 @@ int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
return convert_errno_from_ucl(r);
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
int upx_ucl_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
int method, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
switch (method)
|
switch (method) {
|
||||||
{
|
|
||||||
case M_NRV2B_8:
|
case M_NRV2B_8:
|
||||||
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2b_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2B_LE16:
|
case M_NRV2B_LE16:
|
||||||
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2b_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2B_LE32:
|
case M_NRV2B_LE32:
|
||||||
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2b_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2D_8:
|
case M_NRV2D_8:
|
||||||
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2d_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2D_LE16:
|
case M_NRV2D_LE16:
|
||||||
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2d_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2D_LE32:
|
case M_NRV2D_LE32:
|
||||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2d_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2E_8:
|
case M_NRV2E_8:
|
||||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2e_decompress_safe_8(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2E_LE16:
|
case M_NRV2E_LE16:
|
||||||
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2e_decompress_safe_le16(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2E_LE32:
|
case M_NRV2E_LE32:
|
||||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,nullptr);
|
r = ucl_nrv2e_decompress_safe_le32(src, src_len, dst, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
@@ -195,49 +190,43 @@ int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
return convert_errno_from_ucl(r);
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_ucl_test_overlap ( const upx_bytep buf,
|
int upx_ucl_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
const upx_bytep tbuf,
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
unsigned src_off, unsigned src_len,
|
const upx_compress_result_t *cresult) {
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
int r;
|
int r;
|
||||||
UNUSED(tbuf); // not needed for UCL
|
UNUSED(tbuf); // not needed for UCL
|
||||||
|
|
||||||
switch (method)
|
switch (method) {
|
||||||
{
|
|
||||||
case M_NRV2B_8:
|
case M_NRV2B_8:
|
||||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2b_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2B_LE16:
|
case M_NRV2B_LE16:
|
||||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2b_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2B_LE32:
|
case M_NRV2B_LE32:
|
||||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2b_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2D_8:
|
case M_NRV2D_8:
|
||||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2d_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2D_LE16:
|
case M_NRV2D_LE16:
|
||||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2d_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2D_LE32:
|
case M_NRV2D_LE32:
|
||||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2d_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2E_8:
|
case M_NRV2E_8:
|
||||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2e_test_overlap_8(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2E_LE16:
|
case M_NRV2E_LE16:
|
||||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2e_test_overlap_le16(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
case M_NRV2E_LE32:
|
case M_NRV2E_LE32:
|
||||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,nullptr);
|
r = ucl_nrv2e_test_overlap_le32(buf, src_off, src_len, dst_len, nullptr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown decompression method");
|
||||||
@@ -248,7 +237,6 @@ int upx_ucl_test_overlap ( const upx_bytep buf,
|
|||||||
return convert_errno_from_ucl(r);
|
return convert_errno_from_ucl(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc
|
// misc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@@ -258,8 +246,7 @@ static ucl_voidp __UCL_CDECL my_malloc(ucl_uint n) { return calloc(1, n); }
|
|||||||
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
|
static void __UCL_CDECL my_free(ucl_voidp p) { free(p); }
|
||||||
}
|
}
|
||||||
|
|
||||||
int upx_ucl_init(void)
|
int upx_ucl_init(void) {
|
||||||
{
|
|
||||||
if (ucl_init() != UCL_E_OK)
|
if (ucl_init() != UCL_E_OK)
|
||||||
return -1;
|
return -1;
|
||||||
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
|
if (UCL_VERSION != ucl_version() || strcmp(UCL_VERSION_STRING, ucl_version_string()) != 0)
|
||||||
@@ -268,19 +255,14 @@ int upx_ucl_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *upx_ucl_version_string(void)
|
const char *upx_ucl_version_string(void) { return ucl_version_string(); }
|
||||||
{
|
|
||||||
return ucl_version_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler)
|
unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||||
{
|
|
||||||
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
#if 0 /* UNUSED */
|
||||||
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc)
|
unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||||
{
|
|
||||||
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -308,21 +290,26 @@ static bool check_ucl(const int method, const unsigned expected_c_len) {
|
|||||||
d_buf.allocForDecompression(u_len);
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
c_len = c_buf.getSize() - c_extra;
|
c_len = c_buf.getSize() - c_extra;
|
||||||
r = upx_ucl_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len), &c_len, nullptr, method, level, NULL_cconf, &cresult);
|
r = upx_ucl_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
if (r != 0 || c_len != expected_c_len) return false;
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
d_len = d_buf.getSize();
|
d_len = d_buf.getSize();
|
||||||
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len), &d_len, method, nullptr);
|
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
if (r != 0 || d_len != u_len) return false;
|
&d_len, method, nullptr);
|
||||||
if (memcmp(u_buf, d_buf, u_len) != 0) return false;
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
d_len = u_len - 1;
|
d_len = u_len - 1;
|
||||||
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len), &d_len, method, nullptr);
|
r = upx_ucl_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
if (r == 0) return false;
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
//unsigned x_len = d_len;
|
// unsigned x_len = d_len;
|
||||||
//r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
// r = upx_ucl_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,7 +334,7 @@ TEST_CASE("upx_ucl_decompress") {
|
|||||||
unsigned d_len;
|
unsigned d_len;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
c_data = (C*) "\x92\xff\x10\x00\x00\x00\x00\x00\x48\xff";
|
c_data = (C *) "\x92\xff\x10\x00\x00\x00\x00\x00\x48\xff";
|
||||||
d_len = 16;
|
d_len = 16;
|
||||||
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||||
CHECK((r == 0 && d_len == 16));
|
CHECK((r == 0 && d_len == 16));
|
||||||
@@ -357,7 +344,7 @@ TEST_CASE("upx_ucl_decompress") {
|
|||||||
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
r = upx_ucl_decompress(c_data, 10, d_buf, &d_len, M_NRV2B_8, nullptr);
|
||||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
|
||||||
c_data = (C*) "\x92\xff\x10\x92\x49\x24\x92\xa0\xff";
|
c_data = (C *) "\x92\xff\x10\x92\x49\x24\x92\xa0\xff";
|
||||||
d_len = 16;
|
d_len = 16;
|
||||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||||
CHECK((r == 0 && d_len == 16));
|
CHECK((r == 0 && d_len == 16));
|
||||||
@@ -367,7 +354,7 @@ TEST_CASE("upx_ucl_decompress") {
|
|||||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2D_8, nullptr);
|
||||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
|
||||||
c_data = (C*) "\x90\xff\xb0\x92\x49\x24\x92\xa0\xff";
|
c_data = (C *) "\x90\xff\xb0\x92\x49\x24\x92\xa0\xff";
|
||||||
d_len = 16;
|
d_len = 16;
|
||||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||||
CHECK((r == 0 && d_len == 16));
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
|||||||
+63
-71
@@ -25,16 +25,13 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "util/membuffer.h"
|
#include "util/membuffer.h"
|
||||||
#include <zlib/zlib.h>
|
#include <zlib/zlib.h>
|
||||||
#include <zlib/deflate.h>
|
#include <zlib/deflate.h>
|
||||||
|
|
||||||
|
void zlib_compress_config_t::reset() {
|
||||||
void zlib_compress_config_t::reset()
|
|
||||||
{
|
|
||||||
mem_clear(this, sizeof(*this));
|
mem_clear(this, sizeof(*this));
|
||||||
|
|
||||||
mem_level.reset();
|
mem_level.reset();
|
||||||
@@ -42,40 +39,49 @@ void zlib_compress_config_t::reset()
|
|||||||
strategy.reset();
|
strategy.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int convert_errno_from_zlib(int zr) {
|
||||||
static int convert_errno_from_zlib(int zr)
|
switch (zr) {
|
||||||
{
|
case Z_OK:
|
||||||
switch (zr)
|
return UPX_E_OK;
|
||||||
{
|
// positive values
|
||||||
case Z_OK: return UPX_E_OK;
|
case Z_STREAM_END:
|
||||||
case Z_NEED_DICT: return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
case Z_DATA_ERROR: return UPX_E_ERROR;
|
case Z_NEED_DICT:
|
||||||
case Z_MEM_ERROR: return UPX_E_OUT_OF_MEMORY;
|
return UPX_E_ERROR;
|
||||||
case Z_BUF_ERROR: return UPX_E_OUTPUT_OVERRUN;
|
// negative values
|
||||||
case -7: return UPX_E_INPUT_OVERRUN;
|
case Z_ERRNO:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_STREAM_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_DATA_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
case Z_BUF_ERROR:
|
||||||
|
return UPX_E_OUTPUT_OVERRUN;
|
||||||
|
case Z_VERSION_ERROR:
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
case -7: // UPX extra
|
||||||
|
return UPX_E_INPUT_OVERRUN;
|
||||||
}
|
}
|
||||||
return UPX_E_ERROR;
|
return UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_bytep dst, unsigned* dst_len,
|
upx_callback_p cb_parm, int method, int level,
|
||||||
upx_callback_p cb_parm,
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
int method, int level,
|
|
||||||
const upx_compress_config_t *cconf_parm,
|
|
||||||
upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
assert(level > 0); assert(cresult != nullptr);
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
UNUSED(cb_parm);
|
UNUSED(cb_parm);
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
int zr;
|
int zr;
|
||||||
const zlib_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
||||||
zlib_compress_result_t *res = &cresult->result_zlib;
|
zlib_compress_result_t *const res = &cresult->result_zlib;
|
||||||
|
|
||||||
if (level == 10)
|
if (level == 10)
|
||||||
level = 9;
|
level = 9;
|
||||||
@@ -84,8 +90,7 @@ int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
zlib_compress_config_t::window_bits_t window_bits;
|
zlib_compress_config_t::window_bits_t window_bits;
|
||||||
zlib_compress_config_t::strategy_t strategy;
|
zlib_compress_config_t::strategy_t strategy;
|
||||||
// cconf overrides
|
// cconf overrides
|
||||||
if (lcconf)
|
if (lcconf) {
|
||||||
{
|
|
||||||
oassign(mem_level, lcconf->mem_level);
|
oassign(mem_level, lcconf->mem_level);
|
||||||
oassign(window_bits, lcconf->window_bits);
|
oassign(window_bits, lcconf->window_bits);
|
||||||
oassign(strategy, lcconf->strategy);
|
oassign(strategy, lcconf->strategy);
|
||||||
@@ -102,8 +107,7 @@ int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
|||||||
s.avail_out = *dst_len;
|
s.avail_out = *dst_len;
|
||||||
s.total_in = s.total_out = 0;
|
s.total_in = s.total_out = 0;
|
||||||
|
|
||||||
zr = (int)deflateInit2(&s, level, Z_DEFLATED, 0 - (int)window_bits,
|
zr = (int) deflateInit2(&s, level, Z_DEFLATED, 0 - (int) window_bits, mem_level, strategy);
|
||||||
mem_level, strategy);
|
|
||||||
if (zr != Z_OK)
|
if (zr != Z_OK)
|
||||||
goto error;
|
goto error;
|
||||||
assert(s.state->level == level);
|
assert(s.state->level == level);
|
||||||
@@ -121,8 +125,7 @@ error:
|
|||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
done:
|
done:
|
||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK) {
|
||||||
{
|
|
||||||
if (s.avail_in != 0 || s.total_in != src_len)
|
if (s.avail_in != 0 || s.total_in != src_len)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
}
|
}
|
||||||
@@ -132,16 +135,12 @@ done:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
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, const upx_compress_result_t *cresult) {
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
UNUSED(method);
|
UNUSED(method);
|
||||||
UNUSED(cresult);
|
UNUSED(cresult);
|
||||||
@@ -163,7 +162,7 @@ int upx_zlib_decompress ( const upx_bytep src, unsigned src_len,
|
|||||||
zr = inflate(&s, Z_FINISH);
|
zr = inflate(&s, Z_FINISH);
|
||||||
if (zr != Z_STREAM_END) {
|
if (zr != Z_STREAM_END) {
|
||||||
if (zr == Z_BUF_ERROR && s.avail_in == 0)
|
if (zr == Z_BUF_ERROR && s.avail_in == 0)
|
||||||
zr = -7;
|
zr = -7; // UPX extra
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
zr = inflateEnd(&s);
|
zr = inflateEnd(&s);
|
||||||
@@ -177,8 +176,7 @@ error:
|
|||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK)
|
||||||
r = UPX_E_ERROR;
|
r = UPX_E_ERROR;
|
||||||
done:
|
done:
|
||||||
if (r == UPX_E_OK)
|
if (r == UPX_E_OK) {
|
||||||
{
|
|
||||||
if (s.avail_in != 0 || s.total_in != src_len)
|
if (s.avail_in != 0 || s.total_in != src_len)
|
||||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||||
}
|
}
|
||||||
@@ -188,24 +186,20 @@ done:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// test_overlap - see <ucl/ucl.h> for semantics
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_test_overlap ( const upx_bytep buf,
|
int upx_zlib_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
const upx_bytep tbuf,
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
unsigned src_off, unsigned src_len,
|
const upx_compress_result_t *cresult) {
|
||||||
unsigned* dst_len,
|
|
||||||
int method,
|
|
||||||
const upx_compress_result_t *cresult )
|
|
||||||
{
|
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
|
|
||||||
MemBuffer b(src_off + src_len);
|
MemBuffer b(src_off + src_len);
|
||||||
memcpy(b + src_off, buf + src_off, src_len);
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
unsigned saved_dst_len = *dst_len;
|
unsigned saved_dst_len = *dst_len;
|
||||||
int r = upx_zlib_decompress(raw_index_bytes(b, src_off, src_len), src_len, raw_bytes(b, *dst_len), dst_len, method, cresult);
|
int r = upx_zlib_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||||
|
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||||
if (r != UPX_E_OK)
|
if (r != UPX_E_OK)
|
||||||
return r;
|
return r;
|
||||||
if (*dst_len != saved_dst_len)
|
if (*dst_len != saved_dst_len)
|
||||||
@@ -218,33 +212,26 @@ int upx_zlib_test_overlap ( const upx_bytep buf,
|
|||||||
return UPX_E_OK;
|
return UPX_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// misc
|
// misc
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_init(void)
|
int upx_zlib_init(void) {
|
||||||
{
|
|
||||||
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
if (strcmp(ZLIB_VERSION, zlibVersion()) != 0)
|
||||||
return -2;
|
return -2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *upx_zlib_version_string(void)
|
const char *upx_zlib_version_string(void) { return zlibVersion(); }
|
||||||
{
|
|
||||||
return zlibVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
#if 0 /* UNUSED */
|
||||||
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler)
|
unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler) {
|
||||||
{
|
|
||||||
return adler32(adler, (const Bytef *) buf, len);
|
return adler32(adler, (const Bytef *) buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 /* UNUSED */
|
#if 0 /* UNUSED */
|
||||||
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc)
|
unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) {
|
||||||
{
|
|
||||||
return crc32(crc, (const Bytef *) buf, len);
|
return crc32(crc, (const Bytef *) buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -271,21 +258,26 @@ static bool check_zlib(const int method, const int level, const unsigned expecte
|
|||||||
d_buf.allocForDecompression(u_len);
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
c_len = c_buf.getSize() - c_extra;
|
c_len = c_buf.getSize() - c_extra;
|
||||||
r = upx_zlib_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len), &c_len, nullptr, method, level, NULL_cconf, &cresult);
|
r = upx_zlib_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
if (r != 0 || c_len != expected_c_len) return false;
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
d_len = d_buf.getSize();
|
d_len = d_buf.getSize();
|
||||||
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len), &d_len, method, nullptr);
|
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
if (r != 0 || d_len != u_len) return false;
|
&d_len, method, nullptr);
|
||||||
if (memcmp(u_buf, d_buf, u_len) != 0) return false;
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
d_len = u_len - 1;
|
d_len = u_len - 1;
|
||||||
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len), &d_len, method, nullptr);
|
r = upx_zlib_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
if (r == 0) return false;
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
//unsigned x_len = d_len;
|
// unsigned x_len = d_len;
|
||||||
//r = upx_zlib_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
// r = upx_zlib_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,7 +296,7 @@ TEST_CASE("upx_zlib_decompress") {
|
|||||||
unsigned d_len;
|
unsigned d_len;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
c_data = (C*) "\xfb\xff\x1f\x15\x00\x00";
|
c_data = (C *) "\xfb\xff\x1f\x15\x00\x00";
|
||||||
d_len = 16;
|
d_len = 16;
|
||||||
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||||
CHECK((r == 0 && d_len == 16));
|
CHECK((r == 0 && d_len == 16));
|
||||||
|
|||||||
Reference in New Issue
Block a user