diff --git a/.clang-format b/.clang-format index f6aa154f..18b559ad 100644 --- a/.clang-format +++ b/.clang-format @@ -16,6 +16,7 @@ StatementMacros: [ ACCCHK_ASSERT_IS_SIGNED_T, ACCCHK_ASSERT_IS_UNSIGNED_T, ACCCHK_ASSERT_SIGN_T, + ACC_BLOCK_BEGIN, ACC_COMPILE_TIME_ASSERT, ACC_COMPILE_TIME_ASSERT_HEADER, ACC_CXX_DISABLE_NEW_DELETE, diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml index 341014a8..712b2767 100644 --- a/.github/workflows/close-stale-issues.yml +++ b/.github/workflows/close-stale-issues.yml @@ -1,8 +1,8 @@ # see https://docs.github.com/en/actions/managing-issues-and-pull-requests/closing-inactive-issues # see https://github.com/actions/stale -# Automatically closing issues is far from perfect, but then we only have -# limited resources and this approach favors issues that people +# Automatically closing issues is far from perfect, but then we only +# have limited resources and this approach favors issues that people # actually care about. # # also see: @@ -25,7 +25,9 @@ jobs: steps: - uses: actions/stale@v6 with: -# operations-per-run: 300 + operations-per-run: 300 + exempt-all-milestones: true + exempt-issue-labels: 'blocker,enhancement' days-before-stale: 60 days-before-close: 30 stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Please remove the stale label or add a comment or this issue will be closed in 30 days.' diff --git a/CMakeLists.txt b/CMakeLists.txt index 339c141f..b1acf259 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(",${CMAKE_SOURCE_DIR}," STREQUAL ",${CMAKE_BINARY_DIR},") message(FATAL_ERROR "ERROR: In-source builds are not allowed, please use an extra build dir.") endif() +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) # determine git revision set(GITREV_SHORT "") @@ -61,6 +63,8 @@ if(GITREV_SHORT) if(GIT_DESCRIBE) message(STATUS "UPX_VERSION_GIT_DESCRIBE = \"${GIT_DESCRIBE}\"") endif() +elseif(UPX_CONFIG_DISABLE_GITREV) + message(STATUS "UPX_VERSION_GITREV: disabled") else() message(STATUS "UPX_VERSION_GITREV: not set") endif() @@ -99,6 +103,7 @@ set_property(TARGET upx_vendor_zlib PROPERTY C_STANDARD 11) file(GLOB upx_SOURCES "src/*.cpp" "src/util/*.cpp") list(SORT upx_SOURCES) add_executable(upx ${upx_SOURCES}) +#target_compile_features(upx PRIVATE cxx_std_14) set_property(TARGET upx PROPERTY CXX_STANDARD 14) target_link_libraries(upx upx_vendor_ucl upx_vendor_zlib) @@ -134,8 +139,18 @@ else() add_definitions(-fno-tree-vectorize) endif() +function(upx_sanitize_target t) + if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC) + # default sanitizer for Debug builds + target_compile_options(${t} PRIVATE $<$:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>) + # default sanitizer for Release builds + target_compile_options(${t} PRIVATE $<$:-fstack-protector>) + endif() +endfunction() + set(t upx_vendor_ucl) target_include_directories(${t} PRIVATE vendor/ucl/include vendor/ucl) +upx_sanitize_target(${t}) if(MSVC) target_compile_options(${t} PRIVATE -J -W4 ${warn_WX}) else() @@ -143,6 +158,7 @@ else() endif() set(t upx_vendor_zlib) +upx_sanitize_target(${t}) if(MSVC) target_compile_options(${t} PRIVATE -DHAVE_STDARG_H -DHAVE_VSNPRINTF -J -W3 ${warn_WX}) else() @@ -160,12 +176,7 @@ if(GITREV_SHORT) target_compile_definitions(${t} PRIVATE UPX_VERSION_GIT_DESCRIBE="${GIT_DESCRIBE}") endif() endif() -if(NOT UPX_CONFIG_DISABLE_SANITIZE AND NOT MSVC) - # default sanitizer for Debug builds - target_compile_options(${t} PRIVATE $<$:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fstack-protector-all>) - # default sanitizer for Release builds - target_compile_options(${t} PRIVATE $<$:-fstack-protector>) -endif() +upx_sanitize_target(${t}) if(MSVC) target_compile_options(${t} PRIVATE -EHsc -J -W4 ${warn_WX}) else() diff --git a/doc/Makefile b/doc/Makefile index 759c72ba..c57f0b26 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -12,7 +12,6 @@ empty := space := $(empty) $(empty) tab := $(empty) $(empty) - # /*********************************************************************** # // # ************************************************************************/ @@ -28,22 +27,18 @@ DETAB2 := sed -e 's/$(tab)/ /g' BUILT_SOURCES = upx.1 upx-doc.html upx-doc.txt +#*********************************************************************** +# targets +#*********************************************************************** -### -### targets -### +all: $(BUILT_SOURCES) PHONY -all: $(BUILT_SOURCES) +mostlyclean clean distclean maintainer-clean: PHONY + rm -f $(BUILT_SOURCES) ./pod2htm* -mostlyclean clean distclean maintainer-clean: - rm -f $(BUILT_SOURCES) pod2htm* - -.PHONY: all mostlyclean clean distclean maintainer-clean - - -### -### rules -### +#*********************************************************************** +# rules +#*********************************************************************** .SUFFIXES: .1 .html .man .pod .ps .tex .txt @@ -53,7 +48,7 @@ mostlyclean clean distclean maintainer-clean: %-doc.html : %.pod pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@ - @rm -f pod2htm* + @rm -f ./pod2htm* test -s $@ %.man : %.1 @@ -72,11 +67,10 @@ mostlyclean clean distclean maintainer-clean: pod2text < $< | $(RTRIM) > $@ test -s $@ - -### -### dependencies -### +#*********************************************************************** +# dependencies +#*********************************************************************** $(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST) .DELETE_ON_ERROR: $(BUILT_SOURCES) - +.PHONY: PHONY diff --git a/misc/rebuild-stubs-with-podman/10-create-image.sh b/misc/rebuild-stubs-with-podman/10-create-image.sh index b4f55e58..9a89b858 100755 --- a/misc/rebuild-stubs-with-podman/10-create-image.sh +++ b/misc/rebuild-stubs-with-podman/10-create-image.sh @@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # create the image from Dockerfile # using a rootless Podman container -image=upx-stubtools-20210104-v6 +image=upx-stubtools-20210104-v7 podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" diff --git a/misc/rebuild-stubs-with-podman/20-image-run-shell.sh b/misc/rebuild-stubs-with-podman/20-image-run-shell.sh index 014d8fb1..63a3e60e 100755 --- a/misc/rebuild-stubs-with-podman/20-image-run-shell.sh +++ b/misc/rebuild-stubs-with-podman/20-image-run-shell.sh @@ -6,12 +6,12 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # run an interactive shell in the image # using a rootless Podman container -image=upx-stubtools-20210104-v6 +image=upx-stubtools-20210104-v7 flags=( -ti --read-only --rm ) -flags+=( --cap-drop=all ) # drop all capabilities -flags+=( --network=none ) # no network needed -flags+=( -e TERM="$TERM" ) # pass $TERM +flags+=( --cap-drop=all ) # drop all capabilities +flags+=( --network=none ) # no network needed +flags+=( -e TERM="$TERM" ) # pass $TERM if [[ 1 == 1 ]]; then # run as user upx 2000:2000 flags+=( --user 2000 ) @@ -22,7 +22,7 @@ if [[ 1 == 1 ]]; then # NOTE: we mount the upx top-level directory read-write under /home/upx/src/upx # INFO: SELinux users *may* have to add ":z" to the volume mount flags; check the docs! flags+=( -v "${argv0dir}/../..:/home/upx/src/upx" ) - flags+=( -w /home/upx/src/upx ) # working directory + flags+=( -w /home/upx/src/upx ) # set working directory else # run as user root 0:0 # ONLY FOR DEBUGGING THE IMAGE @@ -44,3 +44,17 @@ podman run "${flags[@]}" "$image" bash -l # # make sure that the stub files did rebuild correctly: # git status . # git diff . + +# we can also build UPX in the container: +# cd /home/upx/src/upx +# rm -rf ./build/release +# make build/release +# # run tests +# ./build/release/upx --version +# make -C build/release test + +# and we can also rebuild the UPX docs the container: +# cd /home/upx/src/upx +# make -C doc clean all +# git status doc +# git diff doc diff --git a/misc/rebuild-stubs-with-podman/Dockerfile b/misc/rebuild-stubs-with-podman/Dockerfile index 4ab2fbf7..907cc414 100644 --- a/misc/rebuild-stubs-with-podman/Dockerfile +++ b/misc/rebuild-stubs-with-podman/Dockerfile @@ -9,11 +9,11 @@ RUN dpkg --add-architecture i386 \ aria2 ca-certificates git less libmpc3 libncurses5 make \ ncurses-term perl-base python2-minimal wget xz-utils \ libc6:i386 zlib1g:i386 \ - # the following packages are not required for rebuilding the stubs, - # but they do make the image more convenient and also allow building + # the following packages are not required for rebuilding the stubs, but + # they do make the image much more convenient and also allow building # the full UPX binary inside the container via CMake: - bzip2 cmake elfutils file g++ libzstd-dev lzop ninja-build patch \ - patchelf pax-utils rsync unzip vim zip zlib1g-dev zsh zstd \ + 7zip bzip2 cmake elfutils file g++ htop libzstd-dev lzip lzop ninja-build \ + p7zip patch patchelf pax-utils rsync unzip vim zip zlib1g-dev zsh zstd \ && true # manually install compat libs from Ubuntu 16.04; REQUIRED diff --git a/src/compress_lzma.cpp b/src/compress_lzma.cpp index cf6e982d..0eea11b1 100644 --- a/src/compress_lzma.cpp +++ b/src/compress_lzma.cpp @@ -42,9 +42,6 @@ #if (ACC_CC_MSC && (_MSC_VER < 1900)) # pragma warning(disable: 4127) // warning C4127: conditional expression is constant #endif -#if (ACC_CC_INTELC_GNUC) -# pragma warning(error: 424) // #424: extra ";" ignored -#endif void lzma_compress_config_t::reset() diff --git a/src/conf.h b/src/conf.h index e50b2505..7680f65a 100644 --- a/src/conf.h +++ b/src/conf.h @@ -295,9 +295,9 @@ typedef upx_int64_t upx_off_t; #define CLANG_FORMAT_DUMMY_STATEMENT /*empty*/ #if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) -# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b))); +# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b))) #elif (ACC_CC_CLANG || ACC_CC_GNUC) -# define attribute_format(a,b) __attribute__((__format__(__printf__,a,b))); +# define attribute_format(a,b) __attribute__((__format__(__printf__,a,b))) #else # define attribute_format(a,b) /*empty*/ #endif diff --git a/src/lefile.cpp b/src/lefile.cpp index d18face9..2fc5cf6c 100644 --- a/src/lefile.cpp +++ b/src/lefile.cpp @@ -36,9 +36,9 @@ LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) { - COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196); - COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24); - COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4); + COMPILE_TIME_ASSERT(sizeof(le_header_t) == 196) + COMPILE_TIME_ASSERT(sizeof(le_object_table_entry_t) == 24) + COMPILE_TIME_ASSERT(sizeof(le_pagemap_entry_t) == 4) memset(&ih,0,sizeof ih); memset(&oh,0,sizeof oh); iobject_table = oobject_table = nullptr; diff --git a/src/p_mach.h b/src/p_mach.h index 6a90ade9..ea1c3fc0 100644 --- a/src/p_mach.h +++ b/src/p_mach.h @@ -111,7 +111,7 @@ __packed_struct(Mach_command) // generic prefix Word data[2]; // because cmdsize >= 16 #define WANT_MACH_SEGMENT_ENUM 1 #include "p_mach_enum.h" -__packed_struct_end(); +__packed_struct_end() template __packed_struct(Mach_segment_command) diff --git a/src/p_ps1.cpp b/src/p_ps1.cpp index 0edc28d5..9630ba9d 100644 --- a/src/p_ps1.cpp +++ b/src/p_ps1.cpp @@ -151,7 +151,7 @@ bool PackPs1::readBkupHeader() return true; } -#define INIT_BH_BKUP(p, l) {(p)->id = '1'; (p)->len = l;} +#define INIT_BH_BKUP(p, l) ACC_BLOCK_BEGIN {(p)->id = '1'; (p)->len = l;} ACC_BLOCK_END #define ADLER16(a) (((a) >> 16) ^ ((a) & 0xffff)) void PackPs1::putBkupHeader(const unsigned char *src, unsigned char *dst, unsigned *len) diff --git a/src/p_tmt.cpp b/src/p_tmt.cpp index 8846efc9..7dc72888 100644 --- a/src/p_tmt.cpp +++ b/src/p_tmt.cpp @@ -46,7 +46,7 @@ static const PackTmt::PackTmt(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; - COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44); + COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44) } diff --git a/src/p_tos.cpp b/src/p_tos.cpp index 5ca4b92a..aae63eb3 100644 --- a/src/p_tos.cpp +++ b/src/p_tos.cpp @@ -46,7 +46,7 @@ static const CLANG_FORMAT_DUMMY_STATEMENT PackTos::PackTos(InputFile *f) : super(f) { bele = &N_BELE_RTP::be_policy; - COMPILE_TIME_ASSERT(FH_SIZE == 28); + COMPILE_TIME_ASSERT(FH_SIZE == 28) COMPILE_TIME_ASSERT_ALIGNED1(tos_header_t) } diff --git a/src/p_unix.cpp b/src/p_unix.cpp index f4aef7de..d0068b6e 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -49,11 +49,11 @@ PackUnix::PackUnix(InputFile *f) : super(f), exetype(0), blocksize(0), overlay_offset(0), lsize(0) { - COMPILE_TIME_ASSERT(sizeof(Elf32_Ehdr) == 52); - COMPILE_TIME_ASSERT(sizeof(Elf32_Phdr) == 32); - COMPILE_TIME_ASSERT(sizeof(b_info) == 12); - COMPILE_TIME_ASSERT(sizeof(l_info) == 12); - COMPILE_TIME_ASSERT(sizeof(p_info) == 12); + COMPILE_TIME_ASSERT(sizeof(Elf32_Ehdr) == 52) + COMPILE_TIME_ASSERT(sizeof(Elf32_Phdr) == 32) + COMPILE_TIME_ASSERT(sizeof(b_info) == 12) + COMPILE_TIME_ASSERT(sizeof(l_info) == 12) + COMPILE_TIME_ASSERT(sizeof(p_info) == 12) } diff --git a/src/p_vmlinz.cpp b/src/p_vmlinz.cpp index 2f7c3720..3cc83723 100644 --- a/src/p_vmlinz.cpp +++ b/src/p_vmlinz.cpp @@ -56,7 +56,7 @@ PackVmlinuzI386::PackVmlinuzI386(InputFile *f) : , filter_len(0) { bele = &N_BELE_RTP::le_policy; - COMPILE_TIME_ASSERT(sizeof(boot_sect_t) == 0x250); + COMPILE_TIME_ASSERT(sizeof(boot_sect_t) == 0x250) } diff --git a/src/pefile.cpp b/src/pefile.cpp index 392896c3..e7bc4c84 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -873,7 +873,7 @@ void PeFile::addStubImports() void PeFile::processImports2(unsigned myimport, unsigned) // pass 2 { - COMPILE_TIME_ASSERT(sizeof(import_desc) == 20); + COMPILE_TIME_ASSERT(sizeof(import_desc) == 20) if (!ilinker) return; @@ -2599,7 +2599,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, callProcessRelocs(rel, ic); // when the resource is put alone into section 3 - const unsigned res_start = (ic + oam1) &~ oam1;; + const unsigned res_start = (ic + oam1) &~ oam1; if (last_section_rsrc_only) callProcessResources(res, ic = res_start); diff --git a/src/util/xspan_impl.h b/src/util/xspan_impl.h index d27f0960..2968668f 100644 --- a/src/util/xspan_impl.h +++ b/src/util/xspan_impl.h @@ -143,34 +143,34 @@ struct Span_is_convertible #if 1 // char => char -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)); +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)) // void => void -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)); +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)) // char => void -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)); +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)) // void => char -ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)); +ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)) // char => int -ACC_COMPILE_TIME_ASSERT_HEADER(!(Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER(!(Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER(!(Span_is_convertible::value)); -ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)); +ACC_COMPILE_TIME_ASSERT_HEADER(!(Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER(!(Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER(!(Span_is_convertible::value)) +ACC_COMPILE_TIME_ASSERT_HEADER((!Span_is_convertible::value)) #endif /*************************************************************************