mirror of
https://github.com/upx/upx.git
synced 2024-11-26 22:20:52 +00:00
src: more cleanups; NFCI
This commit is contained in:
parent
81176716d5
commit
b8b94ee89e
64
src/conf.h
64
src/conf.h
@ -63,7 +63,7 @@
|
||||
#include "miniacc.h"
|
||||
#if !(ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_MSC)
|
||||
// other compilers may work, but we're NOT interested into supporting them
|
||||
# error "only clang and gcc are officially supported"
|
||||
# error "only clang, gcc and msvc are officially supported"
|
||||
#endif
|
||||
// UPX sanity checks for a sane compiler
|
||||
#if !defined(UINT_MAX) || (UINT_MAX != 0xffffffffL)
|
||||
@ -317,28 +317,24 @@ inline void NO_fprintf(FILE *, const char *, ...) {}
|
||||
# define upx_memcpy_inline memcpy
|
||||
#endif
|
||||
|
||||
|
||||
#define __packed_struct(s) struct alignas(1) s {
|
||||
#define __packed_struct_end() };
|
||||
|
||||
#define UNUSED(var) ACC_UNUSED(var)
|
||||
#define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e)
|
||||
|
||||
#define __COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) { \
|
||||
// TODO cleanup: we now require C++14, so remove all __packed_struct usage
|
||||
#define __packed_struct(s) struct alignas(1) s {
|
||||
#define __packed_struct_end() };
|
||||
|
||||
#define COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) { \
|
||||
typedef a acc_tmp_a_t; typedef b acc_tmp_b_t; \
|
||||
__packed_struct(acc_tmp_t) acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; __packed_struct_end() \
|
||||
struct alignas(1) acc_tmp_t { acc_tmp_b_t x; acc_tmp_a_t y; acc_tmp_b_t z; }; \
|
||||
COMPILE_TIME_ASSERT(sizeof(struct acc_tmp_t) == 2*sizeof(b)+sizeof(a)) \
|
||||
COMPILE_TIME_ASSERT(sizeof(((acc_tmp_t*)nullptr)->x)+sizeof(((acc_tmp_t*)nullptr)->y)+sizeof(((acc_tmp_t*)nullptr)->z) == 2*sizeof(b)+sizeof(a)) \
|
||||
}
|
||||
#if defined(__acc_alignof)
|
||||
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b) \
|
||||
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b))
|
||||
#else
|
||||
# define __COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b)
|
||||
#endif
|
||||
#define COMPILE_TIME_ASSERT_ALIGNED1(a) __COMPILE_TIME_ASSERT_ALIGNOF(a,char)
|
||||
#define COMPILE_TIME_ASSERT_ALIGNOF__(a,b) \
|
||||
COMPILE_TIME_ASSERT_ALIGNOF_USING_SIZEOF__(a,b) \
|
||||
COMPILE_TIME_ASSERT(__acc_alignof(a) == sizeof(b)) \
|
||||
COMPILE_TIME_ASSERT(alignof(a) == sizeof(b))
|
||||
#define COMPILE_TIME_ASSERT_ALIGNED1(a) COMPILE_TIME_ASSERT_ALIGNOF__(a,char)
|
||||
|
||||
#define TABLESIZE(table) ((sizeof(table)/sizeof((table)[0])))
|
||||
|
||||
@ -397,23 +393,6 @@ constexpr bool string_ge(const char *a, const char *b) {
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// raw_bytes() - get underlying memory from checked buffers/pointers.
|
||||
// This is overloaded by various utility classes like BoundedPtr,
|
||||
// MemBuffer and Span.
|
||||
//
|
||||
// Note that the pointer type is retained, the "_bytes" hints size_in_bytes
|
||||
**************************************************************************/
|
||||
|
||||
// default: for any regular pointer, raw_bytes() is just the pointer itself
|
||||
template <class T>
|
||||
inline T *raw_bytes(T *ptr, size_t size_in_bytes) {
|
||||
if (size_in_bytes > 0) {
|
||||
assert(ptr != nullptr);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// constants
|
||||
**************************************************************************/
|
||||
@ -815,6 +794,24 @@ int upx_test_overlap ( const upx_bytep buf,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
|
||||
/*************************************************************************
|
||||
// raw_bytes() - get underlying memory from checked buffers/pointers.
|
||||
// This is overloaded by various utility classes like BoundedPtr,
|
||||
// MemBuffer and Span.
|
||||
//
|
||||
// Note that the pointer type is retained, the "_bytes" hints size_in_bytes
|
||||
**************************************************************************/
|
||||
|
||||
// default: for any regular pointer, raw_bytes() is just the pointer itself
|
||||
template <class T>
|
||||
inline T *raw_bytes(T *ptr, size_t size_in_bytes) {
|
||||
if (size_in_bytes > 0) {
|
||||
if __acc_very_unlikely (ptr == nullptr)
|
||||
throwInternalError("raw_bytes unexpected NULL ptr");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
#if (ACC_OS_CYGWIN || ACC_OS_DOS16 || ACC_OS_DOS32 || ACC_OS_EMX || ACC_OS_OS2 || ACC_OS_OS216 || ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||
# if defined(INVALID_HANDLE_VALUE) || defined(MAKEWORD) || defined(RT_CURSOR)
|
||||
@ -822,7 +819,6 @@ int upx_test_overlap ( const upx_bytep buf,
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -193,7 +193,7 @@ public:
|
||||
|
||||
#undef NORET
|
||||
#if 1 && defined(__GNUC__)
|
||||
#define NORET __attribute__((__noreturn__)) __acc_noinline
|
||||
#define NORET __acc_noinline __attribute__((__noreturn__))
|
||||
#else
|
||||
#define NORET __acc_noinline
|
||||
#endif
|
||||
|
@ -75,7 +75,7 @@ options_t *opt = &global_options;
|
||||
**************************************************************************/
|
||||
|
||||
template <size_t N>
|
||||
static void test_options(const char *(&a)[N]) {
|
||||
static inline void test_options(const char *(&a)[N]) {
|
||||
(void) main_get_options((int) (N - 1), ACC_UNCONST_CAST(char **, a));
|
||||
}
|
||||
|
||||
@ -85,42 +85,59 @@ TEST_CASE("getopt") {
|
||||
opt = &local_options;
|
||||
opt->reset();
|
||||
opt->debug.getopt_throw_instead_of_exit = true;
|
||||
const char a0[] = "<argv0>";
|
||||
static const char a0[] = "<argv0>";
|
||||
|
||||
SUBCASE("issue 587a") {
|
||||
SUBCASE("issue 587") {
|
||||
const char *a[] = {a0, "--brute", "--lzma", nullptr};
|
||||
CHECK(!opt->all_methods);
|
||||
test_options(a);
|
||||
CHECK(opt->all_methods);
|
||||
CHECK(opt->all_methods_use_lzma == 1);
|
||||
}
|
||||
SUBCASE("issue 587b") {
|
||||
SUBCASE("issue 587") {
|
||||
const char *a[] = {a0, "--lzma", "--brute", nullptr};
|
||||
CHECK(!opt->all_methods);
|
||||
test_options(a);
|
||||
CHECK(opt->all_methods);
|
||||
CHECK(opt->all_methods_use_lzma == 1);
|
||||
}
|
||||
SUBCASE("issue 587c") {
|
||||
SUBCASE("issue 587") {
|
||||
const char *a[] = {a0, "--brute", "--no-lzma", nullptr};
|
||||
CHECK(!opt->all_methods);
|
||||
test_options(a);
|
||||
CHECK(opt->all_methods);
|
||||
CHECK(opt->all_methods_use_lzma == -1);
|
||||
}
|
||||
SUBCASE("issue 587d") {
|
||||
SUBCASE("issue 587") {
|
||||
const char *a[] = {a0, "--no-lzma", "--brute", nullptr};
|
||||
CHECK(!opt->all_methods);
|
||||
test_options(a);
|
||||
CHECK(opt->all_methods);
|
||||
CHECK(opt->all_methods_use_lzma == -1);
|
||||
}
|
||||
SUBCASE("issue 587e") {
|
||||
const char *a[] = {a0, "--no-lzma", "--all-methods", nullptr};
|
||||
SUBCASE("issue 587") {
|
||||
const char *a[] = {a0, "--no-lzma", "--lzma", nullptr};
|
||||
test_options(a);
|
||||
CHECK(!opt->all_methods);
|
||||
CHECK(opt->all_methods_use_lzma == 1);
|
||||
CHECK(opt->method == M_LZMA);
|
||||
}
|
||||
SUBCASE("issue 587") {
|
||||
const char *a[] = {a0, "--no-lzma", "--lzma", "--brute", nullptr};
|
||||
test_options(a);
|
||||
CHECK(opt->all_methods);
|
||||
CHECK(opt->all_methods_use_lzma == 1);
|
||||
CHECK(opt->method == -1);
|
||||
}
|
||||
SUBCASE("issue 587") {
|
||||
const char *a[] = {a0, "--lzma", "--no-lzma", nullptr};
|
||||
test_options(a);
|
||||
CHECK(!opt->all_methods);
|
||||
CHECK(opt->all_methods_use_lzma == -1);
|
||||
CHECK(opt->method == -1);
|
||||
}
|
||||
SUBCASE("issue 587") {
|
||||
const char *a[] = {a0, "--lzma", "--no-lzma", "--brute", nullptr};
|
||||
test_options(a);
|
||||
CHECK(opt->all_methods);
|
||||
CHECK(opt->all_methods_use_lzma == -1);
|
||||
CHECK(opt->method == -1);
|
||||
}
|
||||
|
||||
opt = saved_opt;
|
||||
|
@ -94,7 +94,7 @@ unsigned UiPacker::update_fu_len = 0;
|
||||
static const char header_line1[] = " File size Ratio Format Name\n";
|
||||
static char header_line2[] = " -------------------- ------ ----------- -----------\n";
|
||||
|
||||
static char progress_filler[] = ".*[]";
|
||||
static char progress_filler[4 + 1] = ".*[]";
|
||||
|
||||
static void init_global_constants(void) {
|
||||
#if 0 && (ACC_OS_DOS16 || ACC_OS_DOS32)
|
||||
@ -399,7 +399,7 @@ void UiPacker::doCallback(unsigned isize, unsigned osize) {
|
||||
char *m = &s->msg_buf[s->bar_pos];
|
||||
*m++ = progress_filler[2];
|
||||
for (i = 0; i < s->bar_len; i++)
|
||||
*m++ = progress_filler[i <= pos];
|
||||
*m++ = progress_filler[i <= pos ? 1 : 0];
|
||||
*m++ = progress_filler[3];
|
||||
|
||||
// compute current compression ratio
|
||||
|
@ -141,10 +141,6 @@ struct TestBELE {
|
||||
COMPILE_TIME_ASSERT(sizeof(test2_t) == 1 + 3 * sizeof(T))
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(test2_t)
|
||||
COMPILE_TIME_ASSERT(sizeof(t2) == 7 + 21 * sizeof(T))
|
||||
#if defined(__acc_alignof)
|
||||
COMPILE_TIME_ASSERT(__acc_alignof(t1) == 1)
|
||||
COMPILE_TIME_ASSERT(__acc_alignof(t2) == 1)
|
||||
#endif
|
||||
#if 1
|
||||
T allbits;
|
||||
allbits = 0;
|
||||
|
@ -107,9 +107,9 @@ static unsigned width(unsigned x) {
|
||||
static inline unsigned umax(unsigned a, unsigned b) { return (a >= b) ? a : b; }
|
||||
|
||||
unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned extra) {
|
||||
size_t const z = uncompressed_size; // fewer keystrokes and display columns
|
||||
size_t const w = umax(8, width(z - 1)); // ignore tiny offsets
|
||||
size_t bytes = mem_size(1, z);
|
||||
unsigned const z = uncompressed_size; // fewer keystrokes and display columns
|
||||
unsigned const w = umax(8, width(z - 1)); // ignore tiny offsets
|
||||
unsigned bytes = ACC_ICONV(unsigned, mem_size(1, z)); // check
|
||||
// Worst matching: All match at max_offset, which implies 3==min_match
|
||||
// All literal: 1 bit overhead per literal byte
|
||||
bytes = umax(bytes, bytes + z / 8);
|
||||
@ -119,11 +119,11 @@ unsigned MemBuffer::getSizeForCompression(unsigned uncompressed_size, unsigned e
|
||||
bytes = umax(bytes, (z / 3 * (8 + 3 * (w - 7) / 2)) / 8);
|
||||
// extra + 256 safety for rounding
|
||||
bytes = mem_size(1, bytes, extra, 256);
|
||||
return ACC_ICONV(unsigned, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
unsigned MemBuffer::getSizeForUncompression(unsigned uncompressed_size, unsigned extra) {
|
||||
size_t bytes = mem_size(1, uncompressed_size, extra);
|
||||
size_t bytes = mem_size(1, uncompressed_size, extra); // check
|
||||
return ACC_ICONV(unsigned, bytes);
|
||||
}
|
||||
|
||||
@ -152,9 +152,9 @@ void MemBuffer::fill(unsigned off, unsigned len, int value) {
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#define PTR(p) ((unsigned) ((upx_uintptr_t)(p) &0xffffffff))
|
||||
#define MAGIC1(p) (PTR(p) ^ 0xfefdbeeb)
|
||||
#define MAGIC2(p) (PTR(p) ^ 0xfefdbeeb ^ 0x80024001)
|
||||
#define PTR_BITS(p) ((unsigned) ((upx_uintptr_t)(p) &0xffffffff))
|
||||
#define MAGIC1(p) ((PTR_BITS(p) ^ 0xfefdbeeb) | 1)
|
||||
#define MAGIC2(p) ((PTR_BITS(p) ^ 0xfefdbeeb ^ 0x80024011) | 1)
|
||||
|
||||
unsigned MemBuffer::global_alloc_counter = 0;
|
||||
|
||||
@ -162,11 +162,11 @@ void MemBuffer::checkState() const {
|
||||
if (!b)
|
||||
throwInternalError("block not allocated");
|
||||
if (use_simple_mcheck()) {
|
||||
if (get_be32(b - 4) != MAGIC1(b))
|
||||
if (get_ne32(b - 4) != MAGIC1(b))
|
||||
throwInternalError("memory clobbered before allocated block 1");
|
||||
if (get_be32(b - 8) != b_size_in_bytes)
|
||||
if (get_ne32(b - 8) != b_size_in_bytes)
|
||||
throwInternalError("memory clobbered before allocated block 2");
|
||||
if (get_be32(b + b_size_in_bytes) != MAGIC2(b))
|
||||
if (get_ne32(b + b_size_in_bytes) != MAGIC2(b))
|
||||
throwInternalError("memory clobbered past end of allocated block");
|
||||
}
|
||||
}
|
||||
@ -181,18 +181,17 @@ void MemBuffer::alloc(upx_uint64_t size) {
|
||||
unsigned char *p = (unsigned char *) malloc(bytes);
|
||||
if (!p)
|
||||
throwOutOfMemoryException();
|
||||
b = p;
|
||||
b_size_in_bytes = ACC_ICONV(unsigned, size);
|
||||
if (use_simple_mcheck()) {
|
||||
b = p + 16;
|
||||
// store magic constants to detect buffer overruns
|
||||
set_be32(b - 8, b_size_in_bytes);
|
||||
set_be32(b - 4, MAGIC1(b));
|
||||
set_be32(b + b_size_in_bytes, MAGIC2(b));
|
||||
set_be32(b + b_size_in_bytes + 4, global_alloc_counter++);
|
||||
} else
|
||||
b = p;
|
||||
|
||||
#if defined(__SANITIZE_ADDRESS__) || DEBUG
|
||||
set_ne32(b - 8, b_size_in_bytes);
|
||||
set_ne32(b - 4, MAGIC1(b));
|
||||
set_ne32(b + b_size_in_bytes, MAGIC2(b));
|
||||
set_ne32(b + b_size_in_bytes + 4, global_alloc_counter++);
|
||||
}
|
||||
#if !defined(__SANITIZE_ADDRESS__) && 0
|
||||
fill(0, b_size_in_bytes, (rand() & 0xff) | 1); // debug
|
||||
(void) VALGRIND_MAKE_MEM_UNDEFINED(b, b_size_in_bytes);
|
||||
#endif
|
||||
@ -203,10 +202,10 @@ void MemBuffer::dealloc() {
|
||||
checkState();
|
||||
if (use_simple_mcheck()) {
|
||||
// clear magic constants
|
||||
set_be32(b - 8, 0);
|
||||
set_be32(b - 4, 0);
|
||||
set_be32(b + b_size_in_bytes, 0);
|
||||
set_be32(b + b_size_in_bytes + 4, 0);
|
||||
set_ne32(b - 8, 0);
|
||||
set_ne32(b - 4, 0);
|
||||
set_ne32(b + b_size_in_bytes, 0);
|
||||
set_ne32(b + b_size_in_bytes + 4, 0);
|
||||
//
|
||||
::free(b - 16);
|
||||
} else
|
||||
@ -218,4 +217,29 @@ void MemBuffer::dealloc() {
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
TEST_CASE("MemBuffer") {
|
||||
MemBuffer mb;
|
||||
CHECK_THROWS(mb.checkState());
|
||||
CHECK_THROWS(mb.alloc(0x30000000 + 1));
|
||||
CHECK(raw_bytes(mb, 0) == nullptr);
|
||||
CHECK_THROWS(raw_bytes(mb, 1));
|
||||
mb.alloc(64);
|
||||
mb.checkState();
|
||||
CHECK(raw_bytes(mb, 64) != nullptr);
|
||||
CHECK(raw_bytes(mb, 64) == mb.getVoidPtr());
|
||||
CHECK_THROWS(raw_bytes(mb, 65));
|
||||
if (use_simple_mcheck()) {
|
||||
upx_byte *b = raw_bytes(mb, 0);
|
||||
unsigned magic1 = get_ne32(b - 4);
|
||||
set_ne32(b - 4, magic1 ^ 1);
|
||||
CHECK_THROWS(mb.checkState());
|
||||
set_ne32(b - 4, magic1);
|
||||
mb.checkState();
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -48,20 +48,24 @@ public:
|
||||
// NOTE: for fully bound-checked pointer use SPAN_S from xspan.h
|
||||
operator pointer() const { return b; }
|
||||
|
||||
template <class U, class V = typename std::enable_if<std::is_integral<U>::value, U>::type>
|
||||
pointer operator+(V n) const {
|
||||
size_t bytes = mem_size(sizeof(T), n); // check
|
||||
return raw_bytes(bytes) + n;
|
||||
template <class U,
|
||||
class /*Dummy*/ = typename std::enable_if<std::is_integral<U>::value, U>::type>
|
||||
pointer operator+(U n) const {
|
||||
size_t bytes = mem_size(sizeof(T), n); // check mem_size
|
||||
return raw_bytes(bytes) + n; // and check bytes
|
||||
}
|
||||
|
||||
// NOT allowed; use raw_bytes() instead
|
||||
template <class U, class V = typename std::enable_if<std::is_integral<U>::value, U>::type>
|
||||
pointer operator-(V n) const = delete;
|
||||
template <class U,
|
||||
class /*Dummy*/ = typename std::enable_if<std::is_integral<U>::value, U>::type>
|
||||
pointer operator-(U n) const = delete;
|
||||
|
||||
pointer raw_bytes(size_t bytes) const {
|
||||
if (bytes > 0) {
|
||||
assert(b != nullptr);
|
||||
assert(bytes <= b_size_in_bytes);
|
||||
if __acc_very_unlikely (b == nullptr)
|
||||
throwInternalError("MemBuffer raw_bytes unexpected NULL ptr");
|
||||
if __acc_very_unlikely (bytes > b_size_in_bytes)
|
||||
throwInternalError("MemBuffer raw_bytes invalid size");
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
@ -31,8 +31,8 @@
|
||||
// UPX version of string functions, with assertions and sane limits
|
||||
**************************************************************************/
|
||||
|
||||
#undef vsnprintf
|
||||
int upx_safe_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap) {
|
||||
#undef vsnprintf
|
||||
size_t size;
|
||||
|
||||
// preconditions
|
||||
@ -56,6 +56,7 @@ int upx_safe_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_l
|
||||
}
|
||||
|
||||
return ACC_ICONV(int, size - 1); // snprintf() returns length, not size
|
||||
#define vsnprintf upx_safe_vsnprintf
|
||||
}
|
||||
|
||||
int upx_safe_snprintf(char *str, upx_rsize_t max_size, const char *format, ...) {
|
||||
@ -113,12 +114,13 @@ char *upx_safe_xprintf(const char *format, ...) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#undef strlen
|
||||
upx_rsize_t upx_safe_strlen(const char *s) {
|
||||
#undef strlen
|
||||
assert(s != nullptr);
|
||||
size_t len = strlen(s);
|
||||
assert(len < UPX_RSIZE_MAX_STR);
|
||||
return len;
|
||||
#define strlen upx_safe_strlen
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -249,20 +249,20 @@ int __acc_cdecl_qsort le64_compare_signed(const void *e1, const void *e2) {
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// find util
|
||||
// find and mem_replace util
|
||||
**************************************************************************/
|
||||
|
||||
int find(const void *b, int blen, const void *what, int wlen) {
|
||||
if (b == nullptr || blen <= 0 || what == nullptr || wlen <= 0)
|
||||
int find(const void *buf, int blen, const void *what, int wlen) {
|
||||
// nullptr is explicitly allowed here
|
||||
if (buf == nullptr || blen <= 0 || what == nullptr || wlen <= 0)
|
||||
return -1;
|
||||
|
||||
int i;
|
||||
const unsigned char *base = (const unsigned char *) b;
|
||||
unsigned char firstc = *(const unsigned char *) what;
|
||||
const unsigned char *b = (const unsigned char *) buf;
|
||||
unsigned char first_byte = *(const unsigned char *) what;
|
||||
|
||||
blen -= wlen;
|
||||
for (i = 0; i <= blen; i++, base++)
|
||||
if (*base == firstc && memcmp(base, what, wlen) == 0)
|
||||
for (int i = 0; i <= blen; i++, b++)
|
||||
if (*b == first_byte && memcmp(b, what, wlen) == 0)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
@ -305,6 +305,7 @@ int find_le64(const void *b, int blen, upx_uint64_t what) {
|
||||
}
|
||||
|
||||
TEST_CASE("find") {
|
||||
CHECK(find(nullptr, -1, nullptr, -1) == -1);
|
||||
static const unsigned char b[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||
CHECK(find(b, 16, b, 0) == -1);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
@ -320,10 +321,12 @@ TEST_CASE("find") {
|
||||
CHECK(find_le32(b, 16, 0x07060504) == 4);
|
||||
CHECK(find_be64(b, 16, 0x08090a0b0c0d0e0fULL) == 8);
|
||||
CHECK(find_le64(b, 16, 0x0f0e0d0c0b0a0908ULL) == 8);
|
||||
CHECK(find_be64(b, 15, 0x08090a0b0c0d0e0fULL) == -1);
|
||||
CHECK(find_le64(b, 15, 0x0f0e0d0c0b0a0908ULL) == -1);
|
||||
}
|
||||
|
||||
int mem_replace(void *bb, int blen, const void *what, int wlen, const void *r) {
|
||||
unsigned char *b = (unsigned char *) bb;
|
||||
int mem_replace(void *buf, int blen, const void *what, int wlen, const void *replacement) {
|
||||
unsigned char *b = (unsigned char *) buf;
|
||||
int boff = 0;
|
||||
int n = 0;
|
||||
|
||||
@ -332,7 +335,7 @@ int mem_replace(void *bb, int blen, const void *what, int wlen, const void *r) {
|
||||
if (off < 0)
|
||||
break;
|
||||
boff += off;
|
||||
memcpy(b + boff, r, wlen);
|
||||
memcpy(b + boff, replacement, wlen);
|
||||
boff += wlen;
|
||||
n++;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ inline bool mem_size_valid_bytes(upx_uint64_t bytes) noexcept { return bytes <=
|
||||
bool mem_size_valid(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1 = 0,
|
||||
upx_uint64_t extra2 = 0) noexcept;
|
||||
|
||||
// new with asserted size; will throw on failure
|
||||
// "new" with asserted size; will throw on failure
|
||||
#define New(type, n) new type[mem_size_get_n(sizeof(type), n)]
|
||||
|
||||
// will throw on invalid size
|
||||
@ -75,8 +75,8 @@ inline void mem_clear(void *p, size_t n) {
|
||||
memset(p, 0, n);
|
||||
}
|
||||
|
||||
// ptrdiff_t with nullptr check and asserted size; will throw on failure
|
||||
// WARNING: returns size_in_bytes, not number of elements!
|
||||
// ptrdiff_t with nullptr checks and asserted size; will throw on failure
|
||||
// NOTE: returns size_in_bytes, not number of elements!
|
||||
int ptr_diff_bytes(const void *a, const void *b);
|
||||
unsigned ptr_udiff_bytes(const void *a, const void *b); // asserts a >= b
|
||||
|
||||
@ -96,6 +96,16 @@ ptr_udiff(const T *a, const U *b) {
|
||||
// misc. support functions
|
||||
**************************************************************************/
|
||||
|
||||
int find(const void *b, int blen, const void *what, int wlen);
|
||||
int find_be16(const void *b, int blen, unsigned what);
|
||||
int find_be32(const void *b, int blen, unsigned what);
|
||||
int find_be64(const void *b, int blen, upx_uint64_t what);
|
||||
int find_le16(const void *b, int blen, unsigned what);
|
||||
int find_le32(const void *b, int blen, unsigned what);
|
||||
int find_le64(const void *b, int blen, upx_uint64_t what);
|
||||
|
||||
int mem_replace(void *b, int blen, const void *what, int wlen, const void *r);
|
||||
|
||||
char *fn_basename(const char *name);
|
||||
int fn_strcmp(const char *n1, const char *n2);
|
||||
char *fn_strlwr(char *n);
|
||||
@ -110,16 +120,6 @@ unsigned get_ratio(upx_uint64_t u_len, upx_uint64_t c_len);
|
||||
bool set_method_name(char *buf, size_t size, int method, int level);
|
||||
void center_string(char *buf, size_t size, const char *s);
|
||||
|
||||
int find(const void *b, int blen, const void *what, int wlen);
|
||||
int find_be16(const void *b, int blen, unsigned what);
|
||||
int find_be32(const void *b, int blen, unsigned what);
|
||||
int find_be64(const void *b, int blen, upx_uint64_t what);
|
||||
int find_le16(const void *b, int blen, unsigned what);
|
||||
int find_le32(const void *b, int blen, unsigned what);
|
||||
int find_le64(const void *b, int blen, upx_uint64_t what);
|
||||
|
||||
int mem_replace(void *b, int blen, const void *what, int wlen, const void *r);
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
SPAN_NAMESPACE_BEGIN
|
||||
|
||||
unsigned long long span_check_stats_check_range;
|
||||
unsigned long long span_check_stats_check_range = 0;
|
||||
|
||||
__acc_noinline void span_fail_nullptr() {
|
||||
throwCantUnpack("span unexpected NULL pointer; take care!");
|
||||
|
@ -52,12 +52,20 @@ pointer ptr; // current view into (base, base+size_in_bytes) iff base != nullptr
|
||||
pointer base;
|
||||
size_type size_in_bytes;
|
||||
|
||||
private:
|
||||
// disable taking the address => force passing by reference
|
||||
// [I'm not too sure about this design decision, but we can always allow it if needed]
|
||||
Self *operator&() const SPAN_DELETED_FUNCTION;
|
||||
// debug - internal sanity check; also serves as pseudo-documentation
|
||||
#if DEBUG || 1
|
||||
__acc_noinline void assertInvariants() const {
|
||||
if __acc_cte (configRequirePtr)
|
||||
assert(ptr != nullptr);
|
||||
if __acc_cte (configRequireBase)
|
||||
assert(base != nullptr);
|
||||
if __acc_cte ((configRequirePtr || ptr != nullptr) && (configRequireBase || base != nullptr))
|
||||
span_check_range(ptr, base, size_in_bytes);
|
||||
}
|
||||
#else
|
||||
__acc_forceinline void assertInvariants() const {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
static __acc_forceinline pointer makeNotNull(pointer p) {
|
||||
if __acc_very_unlikely (p == nullptr)
|
||||
span_fail_nullptr();
|
||||
@ -85,19 +93,6 @@ __acc_forceinline pointer ensureBase() const {
|
||||
span_fail_nullptr();
|
||||
return ptr;
|
||||
}
|
||||
// debug - extra internal sanity checks
|
||||
#if DEBUG || 1
|
||||
__acc_noinline void assertInvariants() const {
|
||||
if __acc_cte (configRequirePtr)
|
||||
assert(ptr != nullptr);
|
||||
if __acc_cte (configRequireBase)
|
||||
assert(base != nullptr);
|
||||
if __acc_cte ((configRequirePtr || ptr != nullptr) && (configRequireBase || base != nullptr))
|
||||
span_check_range(ptr, base, size_in_bytes);
|
||||
}
|
||||
#else
|
||||
__acc_forceinline void assertInvariants() const {}
|
||||
#endif
|
||||
|
||||
public:
|
||||
inline ~CSelf() {}
|
||||
@ -397,6 +392,10 @@ pointer check_add(pointer p, ptrdiff_t n) const {
|
||||
return p;
|
||||
}
|
||||
|
||||
// disable taking the address => force passing by reference
|
||||
// [I'm not too sure about this design decision, but we can always allow it if needed]
|
||||
Self *operator&() const SPAN_DELETED_FUNCTION;
|
||||
|
||||
public: // raw access
|
||||
pointer raw_ptr() const { return ptr; }
|
||||
pointer raw_base() const { return base; }
|
||||
|
@ -64,17 +64,21 @@ public:
|
||||
#endif
|
||||
|
||||
inline ~CSelf() {}
|
||||
inline CSelf() {}
|
||||
inline CSelf() { assertInvariants(); }
|
||||
|
||||
// constructors from pointers
|
||||
CSelf(pointer p) : ptr(makePtr(p)) {}
|
||||
CSelf(pointer p) : ptr(makePtr(p)) { assertInvariants(); }
|
||||
template <class U>
|
||||
CSelf(U *p, SPAN_REQUIRES_CONVERTIBLE_A) : ptr(makePtr(p)) {}
|
||||
CSelf(U *p, SPAN_REQUIRES_CONVERTIBLE_A) : ptr(makePtr(p)) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
// constructors
|
||||
CSelf(const Self &other) : ptr(other.ptr) {}
|
||||
CSelf(const Self &other) : ptr(other.ptr) { assertInvariants(); }
|
||||
template <class U>
|
||||
CSelf(const CSelf<U> &other, SPAN_REQUIRES_CONVERTIBLE_A) : ptr(other.ptr) {}
|
||||
CSelf(const CSelf<U> &other, SPAN_REQUIRES_CONVERTIBLE_A) : ptr(other.ptr) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
Self &assign(const Self &other) {
|
||||
assertInvariants();
|
||||
@ -87,10 +91,11 @@ public:
|
||||
// assignment
|
||||
Self &operator=(const Self &other) { return assign(other); }
|
||||
|
||||
// FIXME: this is not called !!
|
||||
template <class U>
|
||||
SPAN_REQUIRES_CONVERTIBLE_R(Self &)
|
||||
operator=(U *other) {
|
||||
assert(0);
|
||||
// assert(0);
|
||||
return assign(Self(other));
|
||||
}
|
||||
|
||||
@ -98,7 +103,7 @@ public:
|
||||
template <class U>
|
||||
SPAN_REQUIRES_CONVERTIBLE_R(Self &)
|
||||
operator=(const CSelf<U> &other) {
|
||||
assert(0);
|
||||
// assert(0);
|
||||
return assign(Self(other));
|
||||
}
|
||||
|
||||
@ -187,6 +192,7 @@ public: // raw access
|
||||
#undef CSelf
|
||||
};
|
||||
|
||||
// raw_bytes overload
|
||||
template <class T>
|
||||
inline T *raw_bytes(const Ptr<T> &a, size_t size_in_bytes) {
|
||||
return a.raw_bytes(size_in_bytes);
|
||||
|
@ -48,22 +48,30 @@ private:
|
||||
#include "xspan_impl_common.h"
|
||||
public:
|
||||
// constructors from pointers
|
||||
CSelf(pointer first) : ptr(first), base(nullptr), size_in_bytes(0) {}
|
||||
CSelf(pointer first) : ptr(first), base(nullptr), size_in_bytes(0) { assertInvariants(); }
|
||||
|
||||
// constructors
|
||||
CSelf(const Self &other)
|
||||
: ptr(other.ptr), base(other.base), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ptr), base(other.base), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
template <class U>
|
||||
CSelf(const CSelf<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ptr), base(other.base), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ptr), base(other.base), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
// constructors from Span friends
|
||||
template <class U>
|
||||
CSelf(const PtrOrSpan<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ptr), base(other.base), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ptr), base(other.base), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
template <class U>
|
||||
CSelf(const Span<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ptr), base(other.base), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ptr), base(other.base), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
// assignment from Span friends
|
||||
template <class U>
|
||||
@ -82,6 +90,7 @@ public:
|
||||
#undef CSelf
|
||||
};
|
||||
|
||||
// raw_bytes overload
|
||||
template <class T>
|
||||
inline T *raw_bytes(const PtrOrSpanOrNull<T> &a, size_t size_in_bytes) {
|
||||
return a.raw_bytes(size_in_bytes);
|
||||
|
@ -48,23 +48,33 @@ private:
|
||||
#include "xspan_impl_common.h"
|
||||
public:
|
||||
// constructors from pointers
|
||||
CSelf(pointer first) : ptr(makePtr(first)), base(nullptr), size_in_bytes(0) {}
|
||||
CSelf(pointer first) : ptr(makePtr(first)), base(nullptr), size_in_bytes(0) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
// constructors
|
||||
CSelf(const Self &other)
|
||||
: ptr(other.ensurePtr()), base(other.base), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ensurePtr()), base(other.base), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
template <class U>
|
||||
CSelf(const CSelf<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ensurePtr()), base(other.base), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ensurePtr()), base(other.base), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
// constructors from Span friends
|
||||
template <class U>
|
||||
CSelf(const Span<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ensurePtr()), base(other.base), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ensurePtr()), base(other.base), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
#if SPAN_CONFIG_ENABLE_SPAN_CONVERSION
|
||||
template <class U>
|
||||
CSelf(const PtrOrSpanOrNull<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ensurePtr()), base(other.base), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ensurePtr()), base(other.base), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
#endif
|
||||
|
||||
// assignment from Span friends
|
||||
@ -107,6 +117,7 @@ public:
|
||||
#undef CSelf
|
||||
};
|
||||
|
||||
// raw_bytes overload
|
||||
template <class T>
|
||||
inline T *raw_bytes(const PtrOrSpan<T> &a, size_t size_in_bytes) {
|
||||
return a.raw_bytes(size_in_bytes);
|
||||
|
@ -52,19 +52,27 @@ public:
|
||||
|
||||
// constructors
|
||||
CSelf(const Self &other)
|
||||
: ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
template <class U>
|
||||
CSelf(const CSelf<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
// constructors from Span friends
|
||||
#if SPAN_CONFIG_ENABLE_SPAN_CONVERSION
|
||||
template <class U>
|
||||
CSelf(const PtrOrSpanOrNull<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
template <class U>
|
||||
CSelf(const PtrOrSpan<U> &other, SPAN_REQUIRES_CONVERTIBLE_A)
|
||||
: ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {}
|
||||
: ptr(other.ensurePtr()), base(other.ensureBase()), size_in_bytes(other.size_in_bytes) {
|
||||
assertInvariants();
|
||||
}
|
||||
#endif
|
||||
|
||||
// assignment from Span friends
|
||||
@ -109,6 +117,7 @@ public:
|
||||
#undef CSelf
|
||||
};
|
||||
|
||||
// raw_bytes overload
|
||||
template <class T>
|
||||
inline T *raw_bytes(const Span<T> &a, size_t size_in_bytes) {
|
||||
return a.raw_bytes(size_in_bytes);
|
||||
|
Loading…
Reference in New Issue
Block a user