diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96b13d47..055e006b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -384,8 +384,8 @@ jobs: - { zig_target: x86_64-macos.13-none } - { zig_target: x86_64-windows-gnu } env: - # 2023-05-14 - ZIG_DIST_VERSION: 0.11.0-dev.3123+6f418c11e + # 2023-05-19 + ZIG_DIST_VERSION: 0.11.0-dev.3203+7cf2cbb33 # for zig-cc wrapper scripts (see below): ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING ZIG_FLAGS: ${{ matrix.zig_flags }} diff --git a/.github/workflows/minimal-ci.yml b/.github/workflows/minimal-ci.yml index 35ae80b8..7be9d10f 100644 --- a/.github/workflows/minimal-ci.yml +++ b/.github/workflows/minimal-ci.yml @@ -1,13 +1,15 @@ # minimal GitHub CI building UPX with clang and gcc in an Alpine Linux container name: 'CI - Minimal CI with Alpine Linux' - -on: [workflow_dispatch] +on: + schedule: [cron: '50 3 * * 3'] + workflow_dispatch: jobs: job-alpine-cmake: strategy: fail-fast: false - matrix: { container: ['alpine:3.12','alpine:3.18','alpine:edge','i386/alpine:edge'] } +# matrix: { container: ['alpine:3.12','alpine:3.18','alpine:edge','i386/alpine:edge'] } + matrix: { container: ['alpine:3.10','alpine:3.11','alpine:3.12','alpine:3.13','alpine:3.14','alpine:3.15','alpine:3.16','alpine:3.17','alpine:3.18','alpine:edge','i386/alpine:edge'] } name: ${{ format('container {0}', matrix.container) }} runs-on: ubuntu-latest container: ${{ matrix.container }} diff --git a/.github/workflows/test-alpine-linux.yml b/.github/workflows/test-alpine-linux.yml new file mode 100644 index 00000000..14f0b660 --- /dev/null +++ b/.github/workflows/test-alpine-linux.yml @@ -0,0 +1,33 @@ +name: 'Test - Minimal Alpine build' +on: [workflow_dispatch] +jobs: + job-alpine-clang: + strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } } + name: ${{ format('container {0}', matrix.container) }} + runs-on: ubuntu-latest + container: ${{ matrix.container }} + steps: + - name: ${{ format('Build clang {0}', matrix.container) }} + run: | + apk update && apk upgrade && apk add clang cmake make + wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-src.tar.xz + tar -xoaf upx-4.0.2-src.tar.xz + cd upx-4.0.2-src + make build/extra/clang/release CC="clang -static" CXX="clang++ -static" + make -C build/extra/clang/release test + make -C build/extra/clang/release install DESTDIR="$PWD/Install-with-make" + job-alpine-gcc: + strategy: { matrix: { container: ['alpine:edge','i386/alpine:edge'] } } + name: ${{ format('container {0}', matrix.container) }} + runs-on: ubuntu-latest + container: ${{ matrix.container }} + steps: + - name: ${{ format('Build gcc {0}', matrix.container) }} + run: | + apk update && apk upgrade && apk add cmake g++ make + wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-src.tar.xz + tar -xoaf upx-4.0.2-src.tar.xz + cd upx-4.0.2-src + make build/extra/gcc/release CC="gcc -static" CXX="g++ -static" + make -C build/extra/gcc/release test + make -C build/extra/gcc/release install DESTDIR="$PWD/Install-with-make" diff --git a/src/main.cpp b/src/main.cpp index 78f3f704..1ff690ed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -498,6 +498,12 @@ static int do_option(int optc, const char *arg) { case 545: opt->debug.disable_random_id = true; break; + case 546: + opt->debug.use_random_method = true; + break; + case 547: + opt->debug.use_random_filter = true; + break; // misc case 512: @@ -806,10 +812,12 @@ int main_get_options(int argc, char **argv) { // debug options {"debug", 0x10, N, 'D'}, - {"dump-stub-loader", 0x31, N, 544}, // for internal debugging - {"fake-stub-version", 0x31, N, 542}, // for internal debugging - {"fake-stub-year", 0x31, N, 543}, // for internal debugging - {"disable-random-id", 0x10, N, 545}, // for internal debugging + {"dump-stub-loader", 0x31, N, 544}, // for internal debugging + {"fake-stub-version", 0x31, N, 542}, // for internal debugging + {"fake-stub-year", 0x31, N, 543}, // for internal debugging + {"disable-random-id", 0x90, N, 545}, // for internal debugging + {"debug-use-random-method", 0x90, N, 546}, // for internal debugging + {"debug-use-random-filter", 0x90, N, 547}, // for internal debugging // backup options {"backup", 0x10, N, 'k'}, @@ -984,7 +992,7 @@ void main_get_envoptions() { {"verbose", 0, N, 'v'}, // verbose mode // debug options - {"disable-random-id", 0x10, N, 545}, // for internal debugging + {"disable-random-id", 0x90, N, 545}, // for internal debugging // backup options {"backup", 0x10, N, 'k'}, diff --git a/src/options.h b/src/options.h index 1db78476..e58634c5 100644 --- a/src/options.h +++ b/src/options.h @@ -95,7 +95,9 @@ struct Options final { const char *dump_stub_loader; char fake_stub_version[4 + 1]; // for internal debugging char fake_stub_year[4 + 1]; // for internal debugging - bool getopt_throw_instead_of_exit; // for doctest + bool getopt_throw_instead_of_exit; // for internal doctest checks + bool use_random_method; // for internal debugging + bool use_random_filter; // for internal debugging } debug; // overlay handling diff --git a/src/packer.cpp b/src/packer.cpp index 5a28eb23..18cbdab3 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -1030,10 +1030,20 @@ int Packer::prepareMethods(int *methods, int ph_method, const int *all_methods) continue; if (opt->all_methods && opt->all_methods_use_lzma != 1 && M_IS_LZMA(method)) continue; - // use this method + // check duplicate assert(Packer::isValidCompressionMethod(method)); + for (int i = 0; i < nmethods; i++) + assert(method != methods[i]); + // use this method methods[nmethods++] = method; } + // debug + if (opt->debug.use_random_method && nmethods >= 2) { + int method = methods[rand() % nmethods]; + methods[0] = method; + nmethods = 1; + NO_printf("\nuse_random_method = %d\n", method); + } return nmethods; } @@ -1073,8 +1083,11 @@ static int prepareFilters(int *filters, int &filter_strategy, const int *all_fil continue; if (filter_id == 0) continue; - // use this filter + // check duplicate assert(Filter::isValidFilter(filter_id)); + for (int i = 0; i < nfilters; i++) + assert(filter_id != filters[i]); + // use this filter filters[nfilters++] = filter_id; if (filter_strategy >= 0 && nfilters >= filter_strategy) break; @@ -1084,10 +1097,24 @@ done: // filter_strategy now only means "stop after first successful filter" filter_strategy = (filter_strategy < 0) ? -1 : 0; // make sure that we have a "no filter" fallback + bool have_filter0 = false; for (int i = 0; i < nfilters; i++) - if (filters[i] == 0) - return nfilters; - filters[nfilters++] = 0; + if (filters[i] == 0) { + have_filter0 = true; + break; + } + if (!have_filter0) + filters[nfilters++] = 0; + // debug + if (opt->debug.use_random_filter && nfilters >= 3 && filters[nfilters - 1] == 0) { + int filter_id = filters[rand() % (nfilters - 1)]; + if (filter_id > 0) { + filters[0] = filter_id; + filters[1] = 0; + nfilters = 2; + NO_printf("\nuse_random_filter = %d\n", filter_id); + } + } return nfilters; } diff --git a/src/packer_r.cpp b/src/packer_r.cpp index 3d215251..1260622e 100644 --- a/src/packer_r.cpp +++ b/src/packer_r.cpp @@ -42,7 +42,7 @@ unsigned Packer::optimizeReloc(unsigned relocnum, SPAN_P(byte) relocs, SPAN_S(by ptr_check_no_overlap(relocs.data(), relocs.size_bytes(), image.data(image_size), image_size, out.data(), out.size_bytes()); #endif - SPAN_P_VAR(byte, fix, out); + SPAN_S_VAR(byte, fix, out); *big = 0; if (opt->exact) diff --git a/src/util/xspan_impl.h b/src/util/xspan_impl.h index f2566d6c..8afc025b 100644 --- a/src/util/xspan_impl.h +++ b/src/util/xspan_impl.h @@ -144,6 +144,7 @@ struct XSpan_is_convertible #endif #if DEBUG +// need extra parenthesis because the C preprocessor does not understand C++ templates // char => char ACC_COMPILE_TIME_ASSERT_HEADER((XSpan_is_convertible::value)) ACC_COMPILE_TIME_ASSERT_HEADER((XSpan_is_convertible::value)) @@ -165,9 +166,9 @@ ACC_COMPILE_TIME_ASSERT_HEADER((!XSpan_is_convertible::value)) ACC_COMPILE_TIME_ASSERT_HEADER((!XSpan_is_convertible::value)) ACC_COMPILE_TIME_ASSERT_HEADER((!XSpan_is_convertible::value)) // char => int -ACC_COMPILE_TIME_ASSERT_HEADER(!(XSpan_is_convertible::value)) -ACC_COMPILE_TIME_ASSERT_HEADER(!(XSpan_is_convertible::value)) -ACC_COMPILE_TIME_ASSERT_HEADER(!(XSpan_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!XSpan_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!XSpan_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!XSpan_is_convertible::value)) ACC_COMPILE_TIME_ASSERT_HEADER((!XSpan_is_convertible::value)) #endif diff --git a/src/version.h b/src/version.h index ac347f86..896b58ea 100644 --- a/src/version.h +++ b/src/version.h @@ -1,8 +1,8 @@ #define UPX_VERSION_HEX 0x040003 /* 04.00.03 */ #define UPX_VERSION_STRING "4.0.3" #define UPX_VERSION_STRING4 "4.03" -#define UPX_VERSION_DATE "Feb 5th 2023" -#define UPX_VERSION_DATE_ISO "2023-02-05" +#define UPX_VERSION_DATE "May 19th 2023" +#define UPX_VERSION_DATE_ISO "2023-05-19" #define UPX_VERSION_YEAR "2023" /* vim:set ts=4 sw=4 et: */