diff --git a/.github/workflows/github-close-inactive-issues.yml b/.github/workflows/github-close-inactive-issues.yml index 948cc6fd..e3b64a7f 100644 --- a/.github/workflows/github-close-inactive-issues.yml +++ b/.github/workflows/github-close-inactive-issues.yml @@ -14,7 +14,7 @@ name: 'GitHub - Close inactive issues' on: - schedule: [cron: '50 2 * * 3'] # run weekly Wednesday 02:50 UTC + schedule: [cron: '50 0 * * 3'] # run weekly Wednesday 00:50 UTC workflow_dispatch: jobs: close-issues: diff --git a/.github/workflows/static-analyzer-clang-analyzer.yml b/.github/workflows/static-analyzer-clang-analyzer.yml index 3df2f060..3827ec7b 100644 --- a/.github/workflows/static-analyzer-clang-analyzer.yml +++ b/.github/workflows/static-analyzer-clang-analyzer.yml @@ -21,10 +21,12 @@ jobs: run: 'apk update && apk upgrade && apk add clang clang-analyzer cmake g++ git make' - name: ${{ format('Check out UPX {0} source code', github.ref_name) }} run: | - git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx - git -C upx submodule update --init + # this seems to be needed when running in a container (beause of UID mismatch??) + git config --global --add safe.directory '*' + git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx . + git submodule update --init - name: 'Perform clang-analyzer scan-build Analysis Debug' - run: 'make -C upx build/analyze/clang-analyzer/debug' + run: 'make build/analyze/clang-analyzer/debug' - name: 'Perform clang-analyzer scan-build Analysis Release' if: success() || failure() # run this step even if the previous step failed - run: 'make -C upx build/analyze/clang-analyzer/release' + run: 'make build/analyze/clang-analyzer/release' diff --git a/.github/workflows/static-analyzer-clang-tidy.yml b/.github/workflows/static-analyzer-clang-tidy.yml index 46f50319..8f30adc7 100644 --- a/.github/workflows/static-analyzer-clang-tidy.yml +++ b/.github/workflows/static-analyzer-clang-tidy.yml @@ -21,10 +21,12 @@ jobs: run: 'apk update && apk upgrade && apk add clang clang-extra-tools cmake g++ git make python3' - name: ${{ format('Check out UPX {0} source code', github.ref_name) }} run: | - git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx - git -C upx submodule update --init + # this seems to be needed when running in a container (beause of UID mismatch??) + git config --global --add safe.directory '*' + git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx . + git submodule update --init - name: 'Perform clang-tidy Analysis Debug' - run: 'make -C upx -k build/analyze/clang-tidy/debug' + run: 'make -k build/analyze/clang-tidy/debug' - name: 'Perform clang-tidy Analysis Release' if: success() || failure() # run this step even if the previous step failed - run: 'make -C upx -k build/analyze/clang-tidy/release' + run: 'make -k build/analyze/clang-tidy/release' diff --git a/.github/workflows/test-alpine-linux.yml b/.github/workflows/test-alpine-linux.yml index 33e5c094..4cdd85d6 100644 --- a/.github/workflows/test-alpine-linux.yml +++ b/.github/workflows/test-alpine-linux.yml @@ -63,75 +63,3 @@ jobs: with: name: ${{ env.artifact_name }} path: 'upx*/build/*/upx' - - job-alpine-by-hand: # uses a POSIX-compliant shell - # ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues - # ...and also uses ccache as we are running the same build-script again and again - if: ${{ true }} - strategy: { matrix: { container: ['alpine:3.9','alpine:edge'] } } - name: ${{ format('gcc by-hand {0}', matrix.container) }} - runs-on: ubuntu-latest - container: ${{ matrix.container }} - steps: - - name: ${{ format('Install packages {0}', matrix.container) }} - run: | - # install ccache, g++, git and various POSIX shells - shells="bash dash loksh mksh zsh" - case ${{ matrix.container }} in - *:edge) shells="$shells oksh yash" ;; - esac - echo "installing shells: $shells" - apk update && apk upgrade && apk add ccache g++ git $shells - # enable ccache - echo -e "CC=ccache gcc\nCXX=ccache g++ -std=gnu++17" >> $GITHUB_ENV - # this seems to be needed when running in a container (beause of UID mismatch??) - git config --global --add safe.directory '*' - - name: 'Check out code' - uses: actions/checkout@v3 - with: - submodules: true - path: 'upx with space' - - name: 'Build by-hand with bash' - run: 'bash "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with bash --posix' - run: 'bash --posix "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with busybox ash' - run: 'busybox ash "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with busybox sh' - run: 'busybox sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with dash' - run: 'dash "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with loksh' - run: 'ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with loksh -o posix' - run: 'ksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with loksh -o sh' - run: 'ksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with mksh' - run: 'mksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with mksh -o posix' - run: 'mksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with mksh -o sh' - run: 'mksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with oksh' - if: ${{ contains(matrix.container, ':edge') }} - run: 'oksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with oksh -o posix' - if: ${{ contains(matrix.container, ':edge') }} - run: 'oksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with oksh -o sh' - if: ${{ contains(matrix.container, ':edge') }} - run: 'oksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with yash' - if: ${{ contains(matrix.container, ':edge') }} - run: 'yash "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with zsh' - run: 'zsh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with zsh --emulate ksh' - run: 'zsh --emulate ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Build by-hand with zsh --emulate sh' - run: 'zsh --emulate sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' - - name: 'Show ccache stats' - run: | - ccache -s - ccache -p diff --git a/.github/workflows/weekly-ci-bs-by-hand.yml b/.github/workflows/weekly-ci-bs-by-hand.yml new file mode 100644 index 00000000..d1b7ae95 --- /dev/null +++ b/.github/workflows/weekly-ci-bs-by-hand.yml @@ -0,0 +1,83 @@ +# Copyright (C) Markus Franz Xaver Johannes Oberhumer +# BuildSystem: build "by hand" using a POSIX-compliant shell + +name: 'Weekly CI BS - By Hand' +on: + schedule: [cron: '00 1 * * 3'] # run weekly Wednesday 01:00 UTC + workflow_dispatch: +env: + CMAKE_REQUIRED_QUIET: OFF + DEBIAN_FRONTEND: noninteractive + +jobs: + job-alpine-by-hand: # uses a POSIX-compliant shell + # ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues + # ...and also uses ccache as we are running the same build-script again and again + if: ${{ true }} + strategy: { matrix: { container: ['alpine:3.9','alpine:edge'] } } + name: ${{ format('gcc by-hand {0}', matrix.container) }} + runs-on: ubuntu-latest + container: ${{ matrix.container }} + steps: + - name: ${{ format('Install packages {0}', matrix.container) }} + run: | + # install ccache, g++, git and various POSIX shells + shells="bash dash loksh mksh zsh" + case ${{ matrix.container }} in + *:edge) shells="$shells oksh yash" ;; + esac + echo "installing shells: $shells" + apk update && apk upgrade && apk add ccache g++ git $shells + # enable ccache + echo -e "CC=ccache gcc\nCXX=ccache g++ -std=gnu++17" >> $GITHUB_ENV + # this seems to be needed when running in a container (beause of UID mismatch??) + git config --global --add safe.directory '*' + - name: 'Check out code' + uses: actions/checkout@v3 + with: + submodules: true + path: 'upx with space' + - name: 'Build by-hand with bash' + run: 'bash "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with bash --posix' + run: 'bash --posix "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with busybox ash' + run: 'busybox ash "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with busybox sh' + run: 'busybox sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with dash' + run: 'dash "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with loksh' + run: 'ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with loksh -o posix' + run: 'ksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with loksh -o sh' + run: 'ksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with mksh' + run: 'mksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with mksh -o posix' + run: 'mksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with mksh -o sh' + run: 'mksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with oksh' + if: ${{ contains(matrix.container, ':edge') }} + run: 'oksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with oksh -o posix' + if: ${{ contains(matrix.container, ':edge') }} + run: 'oksh -o posix "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with oksh -o sh' + if: ${{ contains(matrix.container, ':edge') }} + run: 'oksh -o sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with yash' + if: ${{ contains(matrix.container, ':edge') }} + run: 'yash "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with zsh' + run: 'zsh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with zsh --emulate ksh' + run: 'zsh --emulate ksh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Build by-hand with zsh --emulate sh' + run: 'zsh --emulate sh "./upx with space/misc/scripts/build_upx_by_hand.sh"' + - name: 'Show ccache stats' + run: | + ccache -s + ccache -p diff --git a/.github/workflows/weekly-ci-cmake-macos-xcode.yml b/.github/workflows/weekly-ci-bs-cmake-macos-xcode.yml similarity index 93% rename from .github/workflows/weekly-ci-cmake-macos-xcode.yml rename to .github/workflows/weekly-ci-bs-cmake-macos-xcode.yml index 7c0aabb0..fef65a28 100644 --- a/.github/workflows/weekly-ci-cmake-macos-xcode.yml +++ b/.github/workflows/weekly-ci-bs-cmake-macos-xcode.yml @@ -1,9 +1,9 @@ # Copyright (C) Markus Franz Xaver Johannes Oberhumer -# build with 'cmake -G Xcode' +# BuildSystem: build with 'cmake -G Xcode' -name: 'Weekly CI - cmake macOS Xcode' +name: 'Weekly CI BS - cmake macOS Xcode' on: - schedule: [cron: '20 3 * * 3'] # run weekly Wednesday 03:20 UTC + schedule: [cron: '10 1 * * 3'] # run weekly Wednesday 01:10 UTC workflow_dispatch: env: CMAKE_REQUIRED_QUIET: OFF @@ -11,8 +11,6 @@ env: jobs: job-cmake-macos-xcode: # uses cmake + xcodebuild - name: ${{ format('{0} cmake Xcode', matrix.os) }} - runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: @@ -20,6 +18,8 @@ jobs: - { os: macos-11, run_test: true } - { os: macos-12, run_test: true } - { os: macos-13, run_test: false } # TODO: enable once UPX fully works on macos-13 + name: ${{ format('{0} cmake Xcode', matrix.os) }} + runs-on: ${{ matrix.os }} steps: - name: 'Check out code' uses: actions/checkout@v3 diff --git a/.github/workflows/weekly-ci-cmake-windows-nmake.yml b/.github/workflows/weekly-ci-bs-cmake-windows-nmake.yml similarity index 94% rename from .github/workflows/weekly-ci-cmake-windows-nmake.yml rename to .github/workflows/weekly-ci-bs-cmake-windows-nmake.yml index 5f3fc821..f26825a3 100644 --- a/.github/workflows/weekly-ci-cmake-windows-nmake.yml +++ b/.github/workflows/weekly-ci-bs-cmake-windows-nmake.yml @@ -1,9 +1,11 @@ # Copyright (C) Markus Franz Xaver Johannes Oberhumer -# build with 'cmake -G "NMake Makefiles"' +# BuildSystem: build with 'cmake -G "NMake Makefiles"' -name: 'Weekly CI - cmake Windows NMake' +# also tests "clang-cl" + +name: 'Weekly CI BS - cmake Windows NMake' on: - schedule: [cron: '30 3 * * 3'] # run weekly Wednesday 03:30 UTC + schedule: [cron: '20 1 * * 3'] # run weekly Wednesday 01:20 UTC workflow_dispatch: env: CMAKE_REQUIRED_QUIET: OFF @@ -11,8 +13,6 @@ env: jobs: job-cmake-windows-nmake: # uses cmake + nmake - name: ${{ format('vs{0} {1} {2}', matrix.vsversion, matrix.arch, matrix.clang_cl && 'clang-cl' || '') }} - runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: @@ -26,6 +26,8 @@ jobs: - { os: windows-2022, vsversion: 2022, arch: amd64_x86 } # clang-cl - { os: windows-2022, vsversion: 2022, arch: amd64, clang_cl: true } + name: ${{ format('vs{0} {1} {2}', matrix.vsversion, matrix.arch, matrix.clang_cl && 'clang-cl' || '') }} + runs-on: ${{ matrix.os }} steps: - name: 'Check out code' uses: actions/checkout@v3 diff --git a/.github/workflows/weekly-ci-alpine-linux.yml b/.github/workflows/weekly-ci-cc-alpine-linux.yml similarity index 96% rename from .github/workflows/weekly-ci-alpine-linux.yml rename to .github/workflows/weekly-ci-cc-alpine-linux.yml index 3b1e8e41..30e3abeb 100644 --- a/.github/workflows/weekly-ci-alpine-linux.yml +++ b/.github/workflows/weekly-ci-cc-alpine-linux.yml @@ -1,16 +1,18 @@ # Copyright (C) Markus Franz Xaver Johannes Oberhumer +# CompilationCheck: test various clang and gcc versions + # Build under various Alpine Linux versions with clang and gcc, and # also test building with C++20 and C++23. # And also uses a subdirectory "upx with space" that contains whitespace in order # to detect possible quoting issues. -# info: Alpine 3.9 has clang-5, cmake-3.13.0 and gcc-8, which nicely -# matches our minimal build requirements +# info: Alpine Linux 3.9 (released Jan 2019) has clang-5, cmake-3.13.0 +# and gcc-8, which nicely matches our minimal build requirements -name: 'Weekly CI - Alpine Linux' +name: 'Weekly CI CC - Alpine Linux' on: - schedule: [cron: '05 3 * * 3'] # run weekly Wednesday 03:05 UTC + schedule: [cron: '00 2 * * 3'] # run weekly Wednesday 02:00 UTC workflow_dispatch: env: CMAKE_REQUIRED_QUIET: OFF diff --git a/.github/workflows/weekly-ci-llvm-mingw.yml b/.github/workflows/weekly-ci-cc-llvm-mingw.yml similarity index 94% rename from .github/workflows/weekly-ci-llvm-mingw.yml rename to .github/workflows/weekly-ci-cc-llvm-mingw.yml index 5fe22513..6e9fee91 100644 --- a/.github/workflows/weekly-ci-llvm-mingw.yml +++ b/.github/workflows/weekly-ci-cc-llvm-mingw.yml @@ -1,9 +1,11 @@ # Copyright (C) Markus Franz Xaver Johannes Oberhumer +# CompilationCheck: test llvm-mingw + # see https://github.com/mstorsjo/llvm-mingw -name: 'Weekly CI - llvm-mingw' +name: 'Weekly CI CC - llvm-mingw' on: - schedule: [cron: '40 3 * * 3'] # run weekly Wednesday 03:40 UTC + schedule: [cron: '20 2 * * 3'] # run weekly Wednesday 02:20 UTC workflow_dispatch: env: CMAKE_REQUIRED_QUIET: OFF @@ -12,8 +14,6 @@ env: jobs: job-llvm-mingw: # uses cmake+make if: ${{ true }} - name: ${{ format('{0} {1}', matrix.name, matrix.llvm_version) }} - runs-on: ubuntu-latest strategy: fail-fast: false matrix: @@ -25,11 +25,13 @@ jobs: llvm_version: 16.0.6 url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230614/llvm-mingw-20230614-ucrt-ubuntu-20.04-x86_64.tar.xz' - name: llvm-mingw-20230811-msvcrt - llvm_version: 17.0.0rc1 + llvm_version: 17.0.0rc2 url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230811/llvm-mingw-20230811-msvcrt-ubuntu-20.04-x86_64.tar.xz' - name: llvm-mingw-20230811-ucrt - llvm_version: 17.0.0rc1 + llvm_version: 17.0.0rc2 url: 'https://github.com/mstorsjo/llvm-mingw/releases/download/20230811/llvm-mingw-20230811-ucrt-ubuntu-20.04-x86_64.tar.xz' + name: ${{ format('{0} {1}', matrix.name, matrix.llvm_version) }} + runs-on: ubuntu-latest steps: - name: 'Check out code' uses: actions/checkout@v3 diff --git a/.github/workflows/weekly-ci-zigcc.yml b/.github/workflows/weekly-ci-cc-zigcc.yml similarity index 98% rename from .github/workflows/weekly-ci-zigcc.yml rename to .github/workflows/weekly-ci-cc-zigcc.yml index 90e0ea2d..4e78a882 100644 --- a/.github/workflows/weekly-ci-zigcc.yml +++ b/.github/workflows/weekly-ci-cc-zigcc.yml @@ -1,9 +1,11 @@ # Copyright (C) Markus Franz Xaver Johannes Oberhumer +# CompilationCheck: test zigcc + # build with "zig cc"; see https://ziglang.org/download/ -name: 'Weekly CI - zigcc' +name: 'Weekly CI CC - zigcc' on: - schedule: [cron: '50 3 * * 3'] # run weekly Wednesday 03:50 UTC + schedule: [cron: '30 2 * * 3'] # run weekly Wednesday 02:30 UTC workflow_dispatch: env: CMAKE_REQUIRED_QUIET: OFF @@ -13,9 +15,6 @@ env: jobs: job-linux-zigcc: # uses cmake + make - name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }} - runs-on: ubuntu-latest - container: 'alpine:3.18' # older versions such as alpine:3.12 also work; no-container also works strategy: fail-fast: false matrix: @@ -43,6 +42,9 @@ jobs: - { zig_target: x86_64-macos.12.0-none } - { zig_target: x86_64-macos.13.0-none } - { zig_target: x86_64-windows-gnu } + name: ${{ format('zigcc {0} {1}', matrix.zig_target, matrix.zig_pic) }} + runs-on: ubuntu-latest + container: 'alpine:3.18' # older versions such as alpine:3.12 also work; no-container also works env: # for zig-cc wrapper scripts (see below): ZIG_CPPFLAGS: -DUPX_DOCTEST_CONFIG_MULTITHREADING diff --git a/.github/workflows/weekly-ci-rt-checkers.yml b/.github/workflows/weekly-ci-rt-checkers.yml new file mode 100644 index 00000000..b20f73c2 --- /dev/null +++ b/.github/workflows/weekly-ci-rt-checkers.yml @@ -0,0 +1,99 @@ +# Copyright (C) Markus Franz Xaver Johannes Oberhumer +# RunTime test + +# runs ASAN, MSAN, qemu and valgrind checkers; slow! + +name: 'Weekly CI RT - ASAN MSAN Valgrind' +on: + schedule: [cron: '00 3 * * 3'] # run weekly Wednesday 03:00 UTC + workflow_dispatch: +env: + CMAKE_REQUIRED_QUIET: OFF + DEBIAN_FRONTEND: noninteractive + +jobs: + job-runtime-checkers: # uses cmake + make + strategy: + fail-fast: false + matrix: + include: + - container: 'alpine:3.18' + release: debug + qemu: 'qemu-x86_64 -cpu Westmere' + - container: 'alpine:3.18' + release: release + qemu: 'qemu-x86_64 -cpu Westmere' + - container: 'alpine:edge' + release: release + qemu: 'qemu-x86_64 -cpu Westmere' + - container: 'i386/alpine:edge' + release: release + qemu: 'qemu-i386' + name: ${{ format('{0} {1}', matrix.container, matrix.release) }} + runs-on: ubuntu-latest + container: ${{ matrix.container }} + env: + release: ${{ matrix.release }} + steps: + - name: ${{ format('Install packages {0} {1}', matrix.container, matrix.release) }} + run: | + apk update && apk upgrade + apk add bash clang cmake compiler-rt coreutils g++ git make qemu-i386 qemu-x86_64 tar valgrind + # this seems to be needed when running in a container (beause of UID mismatch??) + git config --global --add safe.directory '*' + - name: ${{ format('Check out UPX {0} source code', github.ref_name) }} + run: | + git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx . + git submodule update --init + git clone --depth=1 https://github.com/upx/upx-testsuite ../upx-testsuite + - name: 'Build clang-static' + run: | + export CC="clang -static" CXX="clang++ -static" + make UPX_XTARGET=clang-static xtarget/$release + - name: 'Build clang-asan' + if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported + run: | + # unfortunately ASAN does not support static linking + flags="-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fno-omit-frame-pointer -D__SANITIZE_ADDRESS__=1" + export CC="clang $flags" CXX="clang++ $flags" + make UPX_XTARGET=clang-asan xtarget/$release + - name: 'Build clang-msan' + if: ${{ !startsWith(matrix.container, 'i386/') }} # MSAN i386: not supported + run: | + # unfortunately MSAN does not support static linking + flags="-fsanitize=memory -fsanitize=undefined -fno-omit-frame-pointer -D__SANITIZE_ADDRESS__=1 -DDOCTEST_CONFIG_DISABLE=1" + export CC="clang $flags" CXX="clang++ $flags" + make UPX_XTARGET=clang-msan xtarget/$release + - name: 'Make artifact' + run: | + N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-runtime-checkers-${{ matrix.container }}-${{ matrix.release }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') + mkdir -p "tmp/artifact/$N" + (cd build && cp -ai --parents */*/*/upx "../tmp/artifact/$N") + (cd tmp/artifact && tar --sort=name -czf "$N.tar.gz" "$N" && rm -rf "./$N") + # GitHub Actions magic: set "artifact_name" environment value for use in next step + echo "artifact_name=$N" >> $GITHUB_ENV + - name: ${{ format('Upload artifact {0}', env.artifact_name) }} + if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: missing nodejs on host + uses: actions/upload-artifact@v3 + with: + name: ${{ env.artifact_name }} + path: tmp/artifact + - name: 'Run testsuite clang-asan' + if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported + run: | + export ASAN_OPTIONS=detect_invalid_pointer_pairs=2 + env -C build/xtarget/clang-asan/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh + - name: 'Run testsuite clang-msan' + if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported + run: | + env -C build/xtarget/clang-msan/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh + - name: 'Run testsuite clang-static - QEMU' + if: ${{ matrix.qemu }} + run: | + export upx_exe_runner="${{ matrix.qemu }}" + env -C build/xtarget/clang-static/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh + - name: 'Run testsuite clang-static - Valgrind' + if: ${{ true }} # very slow (takes about 30 minutes on current GitHub CI) + run: | + export upx_exe_runner="valgrind --error-exitcode=1 --quiet" + env -C build/xtarget/clang-static/$release "$PWD"/misc/testsuite/upx_testsuite_1.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 4aef09b7..94c9483d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ if(DEFINED UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION) cmake_minimum_required(VERSION "${UPX_CONFIG_CMAKE_MINIMUM_REQUIRED_VERSION}" FATAL_ERROR) else() - cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) # CMake >= 3.8 is needed for CXX_STANDARD 17 + cmake_minimum_required(VERSION 3.8 FATAL_ERROR) # CMake >= 3.8 is needed for CXX_STANDARD 17 endif() # compilation config options diff --git a/src/check/dt_check.cpp b/src/check/dt_check.cpp index 5e3220d3..c66b8f21 100644 --- a/src/check/dt_check.cpp +++ b/src/check/dt_check.cpp @@ -571,6 +571,7 @@ TEST_CASE("working -fno-strict-aliasing") { *pi = -1; ok = *pl != 0; CHECK(ok); + UNUSED(ok); } TEST_CASE("working -fno-strict-overflow") { @@ -588,6 +589,7 @@ TEST_CASE("working -fno-strict-overflow") { i -= 1; ok = i == INT_MAX; CHECK(ok); + UNUSED(ok); } TEST_CASE("libc snprintf") { diff --git a/src/check/dt_xspan.cpp b/src/check/dt_xspan.cpp index 91831181..12992aeb 100644 --- a/src/check/dt_xspan.cpp +++ b/src/check/dt_xspan.cpp @@ -43,6 +43,7 @@ TEST_CASE("raw_bytes ptr") { ptr = buf; CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 1, 1), ptr) == 2u); CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 4, 0), ptr) == 8u); + UNUSED(ptr); } TEST_CASE("raw_bytes bounded array") { @@ -55,6 +56,7 @@ TEST_CASE("raw_bytes bounded array") { CHECK_THROWS(raw_index_bytes(buf, 3, 3)); CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 1, 1), buf) == 2u); CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 4, 0), buf) == 8u); + UNUSED(buf); } /************************************************************************* @@ -405,6 +407,7 @@ TEST_CASE("PtrOrSpan") { CHECK_THROWS(sp_with_base = s0_no_base); // nullptr assignment CHECK_THROWS(sp_with_base = s0_with_base); // nullptr assignment #endif + UNUSED(my_null); } /************************************************************************* @@ -556,6 +559,7 @@ TEST_CASE("Span") { CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1)); } #endif + UNUSED(my_null); } /************************************************************************* @@ -686,6 +690,7 @@ TEST_CASE("PtrOrSpan") { CHECK(my_memcmp_v1(buf, nullptr, 4) == -2); CHECK(my_memcmp_v2(buf + 4, buf + 4, 999) == 0); CHECK(my_memcmp_v2(buf, buf + 2, 3) == 0); + UNUSED(buf); } /************************************************************************* @@ -839,6 +844,7 @@ TEST_CASE("Span codegen") { CHECK(foo(XSPAN_0_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); CHECK(foo(XSPAN_P_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); CHECK(foo(XSPAN_S_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); + UNUSED(buf); } #endif // WITH_XSPAN >= 2 diff --git a/src/compress/compress_lzma.cpp b/src/compress/compress_lzma.cpp index 1f74c1e9..03157d5c 100644 --- a/src/compress/compress_lzma.cpp +++ b/src/compress/compress_lzma.cpp @@ -547,6 +547,7 @@ TEST_CASE("upx_lzma_decompress") { d_len = 15; r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr); CHECK(r == UPX_E_OUTPUT_OVERRUN); + UNUSED(r); } /* vim:set ts=4 sw=4 et: */ diff --git a/src/compress/compress_ucl.cpp b/src/compress/compress_ucl.cpp index c6b1e1f6..d1b413e2 100644 --- a/src/compress/compress_ucl.cpp +++ b/src/compress/compress_ucl.cpp @@ -363,6 +363,7 @@ TEST_CASE("upx_ucl_decompress") { d_len = 15; r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr); CHECK(r == UPX_E_OUTPUT_OVERRUN); + UNUSED(r); } /* vim:set ts=4 sw=4 et: */ diff --git a/src/compress/compress_zlib.cpp b/src/compress/compress_zlib.cpp index 755e367d..0c5aed75 100644 --- a/src/compress/compress_zlib.cpp +++ b/src/compress/compress_zlib.cpp @@ -305,6 +305,7 @@ TEST_CASE("upx_zlib_decompress") { d_len = 15; r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr); CHECK(r == UPX_E_OUTPUT_OVERRUN); + UNUSED(r); } /* vim:set ts=4 sw=4 et: */ diff --git a/src/util/cxxlib.h b/src/util/cxxlib.h index 21cd1be4..0d103520 100644 --- a/src/util/cxxlib.h +++ b/src/util/cxxlib.h @@ -104,12 +104,11 @@ struct TriBool final { static_assert(ThirdValue != 0 && ThirdValue != 1); enum value_type : underlying_type { False = 0, True = 1, Third = ThirdValue }; // constructors - forceinline constexpr TriBool() noexcept : value(False) {} + forceinline constexpr TriBool() noexcept {} forceinline constexpr TriBool(value_type x) noexcept : value(x) {} constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Third)) {} forceinline ~TriBool() noexcept = default; - // access - constexpr value_type getValue() const noexcept { return value; } + // explicit conversion to bool // checks for > 0, so ThirdValue determines if Third is false (the default) or true explicit constexpr operator bool() const noexcept { return value > False; } // query; this is NOT the same as operator bool() @@ -117,19 +116,22 @@ struct TriBool final { constexpr bool isStrictTrue() const noexcept { return value == True; } constexpr bool isStrictBool() const noexcept { return value == False || value == True; } constexpr bool isThird() const noexcept { return value != False && value != True; } + // access + constexpr value_type getValue() const noexcept { return value; } + // equality constexpr bool operator==(TriBool other) const noexcept { return value == other.value; } constexpr bool operator==(value_type other) const noexcept { return value == other; } constexpr bool operator==(promoted_type other) const noexcept { return value == other; } - // "third" can mean many things, depending on usage context, so provide some alternative names: + // "Third" can mean many things, depending on usage context, so provide some alternative names: // constexpr bool isDefault() const noexcept { return isThird(); } // might be misleading constexpr bool isIndeterminate() const noexcept { return isThird(); } constexpr bool isOther() const noexcept { return isThird(); } constexpr bool isUndecided() const noexcept { return isThird(); } // constexpr bool isUnset() const noexcept { return isThird(); } // might be misleading - // protected: - value_type value; +private: + value_type value = False; // the actual value of this type }; typedef TriBool<> tribool; @@ -147,6 +149,9 @@ struct OptVar final { static constexpr T max_value = max_value_; static_assert(min_value <= default_value && default_value <= max_value); + // automatic conversion + constexpr operator T() const noexcept { return value; } + static void assertValue(const T &value) noexcept { // info: this generates annoying warnings "unsigned >= 0 is always true" // assert_noexcept(value >= min_value); @@ -155,7 +160,7 @@ struct OptVar final { } void assertValue() const noexcept { assertValue(value); } - constexpr OptVar() noexcept : value(default_value), is_set(false) {} + constexpr OptVar() noexcept {} OptVar &operator=(const T &other) noexcept { assertValue(other); value = other; @@ -167,11 +172,9 @@ struct OptVar final { value = default_value; is_set = false; } - constexpr operator T() const noexcept { return value; } - // protected: - T value; - bool is_set; + value_type value = default_value; + bool is_set = false; }; // optional assignments @@ -184,9 +187,8 @@ inline void oassign(OptVar &self, const OptVar &other) n } template inline void oassign(T &v, const OptVar &other) noexcept { - if (other.is_set) { + if (other.is_set) v = other.value; - } } /************************************************************************* diff --git a/src/util/util.cpp b/src/util/util.cpp index bfa6879e..bb737715 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -140,6 +140,7 @@ TEST_CASE("ptr_diff") { CHECK(ptr_udiff(buf, buf) == 0); CHECK(ptr_udiff(buf + 1, buf) == 1); CHECK_THROWS(ptr_udiff(buf, buf + 1)); + UNUSED(buf); } // check that 2 buffers do not overlap; will throw on error @@ -174,7 +175,7 @@ void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, s throwCantPack("ptr_check_no_overlap-bc"); } -#if DEBUG +#if !defined(DOCTEST_CONFIG_DISABLE) && DEBUG TEST_CASE("ptr_check_no_overlap 2") { byte p[4] = {}; @@ -287,7 +288,7 @@ void upx_stable_sort(void *array, size_t n, size_t element_size, } } -#if DEBUG +#if !defined(DOCTEST_CONFIG_DISABLE) && DEBUG TEST_CASE("upx_stable_sort") { { unsigned a[] = {0, 1}; @@ -518,6 +519,7 @@ TEST_CASE("find") { CHECK(find_le64(b, 16, 0x0f0e0d0c0b0a0908ULL) == 8); CHECK(find_be64(b, 15, 0x08090a0b0c0d0e0fULL) == -1); CHECK(find_le64(b, 15, 0x0f0e0d0c0b0a0908ULL) == -1); + UNUSED(b); } int mem_replace(void *buf, int blen, const void *what, int wlen, const void *replacement) noexcept { @@ -545,6 +547,7 @@ TEST_CASE("mem_replace") { CHECK(mem_replace(b + 8, 8, "bbb", 3, "efg") == 2); CHECK(mem_replace(b, 16, "b", 1, "h") == 2); CHECK(strcmp(b, "cdcdcdcdefgefghh") == 0); + UNUSED(b); } /************************************************************************* diff --git a/src/util/xspan_impl.h b/src/util/xspan_impl.h index 75139575..5de3f0a3 100644 --- a/src/util/xspan_impl.h +++ b/src/util/xspan_impl.h @@ -209,8 +209,8 @@ XSPAN_NAMESPACE_END // poison a pointer: point to a non-null invalid address // - resulting pointer should crash on dereference // - this should be efficient (so no mmap() guard page etc.) -// - this should play nice with runtime checkers like ASAN, valgrind, etc. -// - this should play nice with static analyzers like clang-tidy +// - this should play nice with runtime checkers like ASAN, MSAN, valgrind, etc. +// - this should play nice with static analyzers like clang-tidy etc. static forceinline void *XSPAN_GET_POISON_VOID_PTR() { // return (void *) (upx_uintptr_t) 251; // NOLINT(performance-no-int-to-ptr) return (void *) 251;