diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8df9f013..d741186a 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-06-06 - ZIG_DIST_VERSION: 0.11.0-dev.3381+9ee0a706d + # 2023-06-08 + ZIG_DIST_VERSION: 0.11.0-dev.3384+00ff65357 # 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 25f81d6f..0d3e02ae 100644 --- a/.github/workflows/minimal-ci.yml +++ b/.github/workflows/minimal-ci.yml @@ -13,16 +13,25 @@ jobs: name: ${{ format('container {0}', matrix.container) }} runs-on: ubuntu-latest container: ${{ matrix.container }} + env: { VERBOSE: 1 } steps: - name: ${{ format('Install packages {0}', matrix.container) }} - run: 'apk update && apk upgrade && apk add bash clang cmake g++ git make' + run: 'apk update && apk upgrade && apk add clang 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 + x="$(apk list -I "$(apk info -Wq "$(which clang)")")"; echo "clang_package=${x%% *}" >> $GITHUB_ENV + x="$(apk list -I "$(apk info -Wq "$(which gcc)")")"; echo "gcc_package=${x%% *}" >> $GITHUB_ENV echo "artifact_name=upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-minimal-ci-${{ matrix.container }}" | sed 's/[^=0-9a-zA-Z_.-]/-/g' >> $GITHUB_ENV - - { name: 'Build clang', run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"' } - - { name: 'Build gcc', run: 'make -C upx UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static"' } + - name: ${{ format('Build clang Release with {0}', env.clang_package) }} + run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static"' + - name: ${{ format('Build clang Debug with {0}', env.clang_package) }} + run: 'make -C upx UPX_XTARGET=clang-static CC="clang -static" CXX="clang++ -static" xtarget/debug' + - name: ${{ format('Build gcc Release with {0}', env.gcc_package) }} + run: 'make -C upx UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static"' + - name: ${{ format('Build gcc Debug with {0}', env.gcc_package) }} + run: 'make -C upx UPX_XTARGET=gcc-static CC="gcc -static" CXX="g++ -static" xtarget/debug' - { name: 'Strip release binaries', run: 'strip -p --strip-unneeded upx/build/*/*/release/upx' } - name: ${{ format('Upload artifact {0}', env.artifact_name) }} if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: missing nodejs on host @@ -30,5 +39,7 @@ jobs: with: name: ${{ env.artifact_name }} path: 'upx*/build/*/*/*/upx' - - { name: 'Run basic tests clang', run: 'make -C upx/build/xtarget/clang-static/release test' } - - { name: 'Run basic tests gcc', run: 'make -C upx/build/xtarget/gcc-static/release test' } + - { name: 'Run basic tests clang Release', run: 'make -C upx/build/xtarget/clang-static/release test' } + - { name: 'Run basic tests clang Debug', run: 'make -C upx/build/xtarget/clang-static/debug test' } + - { name: 'Run basic tests gcc Release', run: 'make -C upx/build/xtarget/gcc-static/release test' } + - { name: 'Run basic tests gcc Debug', run: 'make -C upx/build/xtarget/gcc-static/debug test' } diff --git a/CMakeLists.txt b/CMakeLists.txt index 30874644..1c245635 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -333,8 +333,8 @@ if(NOT UPX_CONFIG_CMAKE_DISABLE_INSTALL) # installation prefix and directories if(NOT CMAKE_INSTALL_PREFIX) - #message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined.") - message(WARNING "WARNING: CMAKE_INSTALL_PREFIX is not defined.") + #message(FATAL_ERROR "ERROR: CMAKE_INSTALL_PREFIX is not defined") + message(WARNING "WARNING: CMAKE_INSTALL_PREFIX is not defined") endif() if(CMAKE_INSTALL_PREFIX) include(GNUInstallDirs) diff --git a/Makefile b/Makefile index c2a19005..06a59cbb 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ CMAKE = cmake UPX_CMAKE_BUILD_FLAGS += --parallel ifneq ($(VERBOSE),) - UPX_CMAKE_BUILD_FLAGS += --verbose + #UPX_CMAKE_BUILD_FLAGS += --verbose # requires CMake >= 3.14 UPX_CMAKE_CONFIG_FLAGS += -DCMAKE_VERBOSE_MAKEFILE=ON endif # enable this if you prefer Ninja for the actual builds: diff --git a/README.SRC b/README.SRC index 3112f909..e83b1753 100644 --- a/README.SRC +++ b/README.SRC @@ -44,7 +44,7 @@ Short overview Tools needed to build/modify the UPX sources -------------------------------------------- - - A C++ compiler that supports C++ 17: clang-5, gcc-8 or msvc-2019 16.11 + - A C++ compiler that supports C++17: clang-5, gcc-8 or msvc-2019 16.11 (older or other compilers may work but are unsupported, use at your own risk) - GNU make diff --git a/doc/upx.1 b/doc/upx.1 index 84b4b67a..9de91542 100644 --- a/doc/upx.1 +++ b/doc/upx.1 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "UPX 1" -.TH UPX 1 "2023-02-05" "upx 4.0.3" " " +.TH UPX 1 "2023-05-28" "upx 4.1.0" " " .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/misc/cross-compile-upx-with-podman/30-list-packages.sh b/misc/cross-compile-upx-with-podman/11-list-packages.sh similarity index 85% rename from misc/cross-compile-upx-with-podman/30-list-packages.sh rename to misc/cross-compile-upx-with-podman/11-list-packages.sh index 43dac592..f523edfb 100755 --- a/misc/cross-compile-upx-with-podman/30-list-packages.sh +++ b/misc/cross-compile-upx-with-podman/11-list-packages.sh @@ -16,4 +16,4 @@ echo 'Packages:' flags=( --read-only --rm --pull=never ) flags+=( --cap-drop=all ) # drop all capabilities flags+=( --network=none ) # no network needed -podman run "${flags[@]}" "$image" bash -c 'dpkg -l | LC_ALL=C sort' +podman run "${flags[@]}" "$image" bash -c $'dpkg -l | sed \'s/ *$//\' | LC_ALL=C sort' diff --git a/misc/rebuild-stubs-with-podman/30-list-packages.sh b/misc/rebuild-stubs-with-podman/11-list-packages.sh similarity index 85% rename from misc/rebuild-stubs-with-podman/30-list-packages.sh rename to misc/rebuild-stubs-with-podman/11-list-packages.sh index 2b1456a4..66505d9a 100755 --- a/misc/rebuild-stubs-with-podman/30-list-packages.sh +++ b/misc/rebuild-stubs-with-podman/11-list-packages.sh @@ -16,4 +16,4 @@ echo 'Packages:' flags=( --read-only --rm --pull=never ) flags+=( --cap-drop=all ) # drop all capabilities flags+=( --network=none ) # no network needed -podman run "${flags[@]}" "$image" bash -c 'dpkg -l | LC_ALL=C sort' +podman run "${flags[@]}" "$image" bash -c $'dpkg -l | sed \'s/ *$//\' | LC_ALL=C sort' diff --git a/src/bele.h b/src/bele.h index 0daf72b5..23bb31dc 100644 --- a/src/bele.h +++ b/src/bele.h @@ -743,10 +743,10 @@ namespace N_BELE_RTP { // util namespace N_BELE_CTP { -inline const N_BELE_RTP::AbstractPolicy *getRTP(const BEPolicy * /*dummy*/) { +inline const N_BELE_RTP::AbstractPolicy *getRTP(const BEPolicy * /*dummy*/) noexcept { return &N_BELE_RTP::be_policy; } -inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) { +inline const N_BELE_RTP::AbstractPolicy *getRTP(const LEPolicy * /*dummy*/) noexcept { return &N_BELE_RTP::le_policy; } } // namespace N_BELE_CTP diff --git a/src/bele_policy.h b/src/bele_policy.h index cfc11598..38f5cc52 100644 --- a/src/bele_policy.h +++ b/src/bele_policy.h @@ -78,9 +78,10 @@ struct AbstractPolicy { S u64_compare_signed(const void *a, const void *b) C = 0; private: - // disable copy, assignment and move assignment + // disable copy and move AbstractPolicy(const AbstractPolicy &) = delete; AbstractPolicy &operator=(const AbstractPolicy &) = delete; + AbstractPolicy(AbstractPolicy &&) = delete; AbstractPolicy &operator=(AbstractPolicy &&) = delete; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE @@ -145,9 +146,10 @@ struct BEPolicy } private: - // disable copy, assignment and move assignment + // disable copy and move BEPolicy(const BEPolicy &) = delete; BEPolicy &operator=(const BEPolicy &) = delete; + BEPolicy(BEPolicy &&) = delete; BEPolicy &operator=(BEPolicy &&) = delete; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE @@ -206,9 +208,10 @@ struct LEPolicy } private: - // disable copy, assignment and move assignment + // disable copy and move LEPolicy(const LEPolicy &) = delete; LEPolicy &operator=(const LEPolicy &) = delete; + LEPolicy(LEPolicy &&) = delete; LEPolicy &operator=(LEPolicy &&) = delete; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE diff --git a/src/check/dt_xspan.cpp b/src/check/dt_xspan.cpp index d0ff9ba8..b729c23b 100644 --- a/src/check/dt_xspan.cpp +++ b/src/check/dt_xspan.cpp @@ -742,30 +742,52 @@ TEST_CASE("PtrOrSpan char") { } TEST_CASE("PtrOrSpan int") { - int buf[8] = {0, 1, 2, 3, 4, 5, 6, 7}; - XSPAN_P(int) a(buf, XSpanCount(8)); + int buf[8] = {0, 11, 22, 33, 44, 55, 66, 77}; + XSPAN_P(const int) a(buf, XSpanCount(8)); CHECK(a.raw_size_in_bytes() == 8 * sizeof(int)); - XSPAN_P(int) b = a.subspan(0, 7); + XSPAN_P(const int) b = a.subspan(0, 7); CHECK(b.raw_size_in_bytes() == 7 * sizeof(int)); - XSPAN_P(int) c = (b + 1).subspan(0, 6); + XSPAN_P(const int) c = (b + 1).subspan(0, 6); CHECK(c.raw_size_in_bytes() == 6 * sizeof(int)); a += 1; - CHECK(*a == 1); - CHECK(*a++ == 1); - CHECK(*++a == 3); - CHECK(--*a == 2); - CHECK(*a-- == 2); + CHECK(a == buf + 1); + CHECK(*a == 11); + CHECK(*a++ == 11); + CHECK(a == buf + 2); + CHECK(*a == 22); + CHECK(*++a == 33); + CHECK(a == buf + 3); + CHECK(*a == 33); + CHECK(*--a == 22); + CHECK(a == buf + 2); + CHECK(*a == 22); + CHECK(*a-- == 22); + CHECK(a == buf + 1); + CHECK(*a == 11); CHECK(*b == 0); - CHECK(*c == 1); - a = buf + 7; + CHECK(*c == 11); + a -= 1; + a += 7; #ifdef UPX_VERSION_HEX - CHECK(get_le32(a) == ne32_to_le32(7)); + CHECK(get_le32(a) == ne32_to_le32(77)); #endif a++; #ifdef UPX_VERSION_HEX CHECK_THROWS(get_le32(a)); #endif CHECK_THROWS(raw_bytes(a, 1)); + CHECK_THROWS(a++); + CHECK_THROWS(++a); + CHECK_THROWS(a += 1); + CHECK(a == buf + 8); + a = buf; + CHECK_THROWS(a--); + CHECK_THROWS(--a); + CHECK_THROWS(a -= 1); + CHECK_THROWS(a += 9); + CHECK(a == buf); + a += 8; + CHECK(a == buf + 8); } /************************************************************************* @@ -780,6 +802,9 @@ __acc_static_noinline int foo(T p) { r += *++p; p += 3; r += *p; + r += *--p; + r += *p--; + r += *p; return r; } @@ -801,11 +826,14 @@ make_span_s(T *ptr, size_t count) { } // namespace TEST_CASE("Span codegen") { - char buf[8] = {0, 1, 2, 3, 4, 5, 6, 7}; - CHECK(foo(buf) == 0 + 2 + 5); - CHECK(foo(make_span_0(buf, 8)) == 0 + 2 + 5); - CHECK(foo(make_span_p(buf, 8)) == 0 + 2 + 5); - CHECK(foo(make_span_s(buf, 8)) == 0 + 2 + 5); + upx_uint8_t buf[8] = {0, 1, 2, 3, 4, 5, 6, 7}; + CHECK(foo(buf) == 0 + 2 + 5 + 4 + 4 + 3); + CHECK(foo(make_span_0(buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); + CHECK(foo(make_span_p(buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); + CHECK(foo(make_span_s(buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3); + 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); } #endif // WITH_XSPAN >= 2 diff --git a/src/compress/compress_lzma.cpp b/src/compress/compress_lzma.cpp index c4f9c869..11d84b44 100644 --- a/src/compress/compress_lzma.cpp +++ b/src/compress/compress_lzma.cpp @@ -41,7 +41,7 @@ #pragma warning(disable : 4127) // warning C4127: conditional expression is constant #endif -void lzma_compress_config_t::reset() { +void lzma_compress_config_t::reset() noexcept { pos_bits.reset(); lit_pos_bits.reset(); lit_context_bits.reset(); diff --git a/src/compress/compress_zlib.cpp b/src/compress/compress_zlib.cpp index 0e3828be..8b0b3e5f 100644 --- a/src/compress/compress_zlib.cpp +++ b/src/compress/compress_zlib.cpp @@ -30,7 +30,7 @@ #include #include -void zlib_compress_config_t::reset() { +void zlib_compress_config_t::reset() noexcept { mem_clear(this, sizeof(*this)); mem_level.reset(); diff --git a/src/compress/compress_zstd.cpp b/src/compress/compress_zstd.cpp index fed3dc9f..d431f86a 100644 --- a/src/compress/compress_zstd.cpp +++ b/src/compress/compress_zstd.cpp @@ -26,7 +26,7 @@ #include "../conf.h" -void zstd_compress_config_t::reset() { mem_clear(this, sizeof(*this)); } +void zstd_compress_config_t::reset() noexcept { mem_clear(this, sizeof(*this)); } #if WITH_ZSTD #include "compress.h" diff --git a/src/conf.h b/src/conf.h index a95dfd48..6bc5942f 100644 --- a/src/conf.h +++ b/src/conf.h @@ -382,15 +382,14 @@ ACC_COMPILE_TIME_ASSERT_HEADER(usizeof(int) == sizeof(int)) // An Array allocates memory on the heap, and automatically // gets destructed when leaving scope or on exceptions. -#define Array(type, var, size) \ - MemBuffer var ## _membuf(mem_size(sizeof(type), size)); \ +#define Array(type, var, n) \ + MemBuffer var ## _membuf(mem_size(sizeof(type), (n))); \ type * const var = ACC_STATIC_CAST(type *, var ## _membuf.getVoidPtr()) -#define ByteArray(var, size) Array(byte, var, size) +#define ByteArray(var, n) Array(byte, var, (n)) -class noncopyable -{ +class noncopyable { protected: inline noncopyable() noexcept {} inline ~noncopyable() noexcept {} @@ -597,12 +596,12 @@ struct upx_callback_t **************************************************************************/ template -struct OptVar -{ +struct OptVar { typedef T value_type; static constexpr T default_value = default_value_; static constexpr T min_value = min_value_; static constexpr T max_value = max_value_; + static_assert(min_value <= default_value && default_value <= max_value); static void assertValue(const T &v) { // info: this generates annoying warnings "unsigned >= 0 is always true" @@ -659,12 +658,12 @@ struct lzma_compress_config_t unsigned max_num_probs; - void reset(); + void reset() noexcept; }; struct ucl_compress_config_t : public REAL_ucl_compress_config_t { - void reset() { memset(this, 0xff, sizeof(*this)); } + void reset() noexcept { memset(this, 0xff, sizeof(*this)); } }; struct zlib_compress_config_t @@ -677,14 +676,14 @@ struct zlib_compress_config_t window_bits_t window_bits; // wb strategy_t strategy; // st - void reset(); + void reset() noexcept; }; struct zstd_compress_config_t { unsigned dummy; - void reset(); + void reset() noexcept; }; struct upx_compress_config_t @@ -693,7 +692,7 @@ struct upx_compress_config_t ucl_compress_config_t conf_ucl; zlib_compress_config_t conf_zlib; zstd_compress_config_t conf_zstd; - void reset() { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); } + void reset() noexcept { conf_lzma.reset(); conf_ucl.reset(); conf_zlib.reset(); conf_zstd.reset(); } }; #define NULL_cconf ((upx_compress_config_t *) nullptr) @@ -714,28 +713,28 @@ struct lzma_compress_result_t unsigned match_finder_cycles; unsigned num_probs; // (computed result) - void reset() { memset(this, 0, sizeof(*this)); } + void reset() noexcept { memset(this, 0, sizeof(*this)); } }; struct ucl_compress_result_t { ucl_uint result[16]; - void reset() { memset(this, 0, sizeof(*this)); } + void reset() noexcept { memset(this, 0, sizeof(*this)); } }; struct zlib_compress_result_t { unsigned dummy; - void reset() { memset(this, 0, sizeof(*this)); } + void reset() noexcept { memset(this, 0, sizeof(*this)); } }; struct zstd_compress_result_t { unsigned dummy; - void reset() { memset(this, 0, sizeof(*this)); } + void reset() noexcept { memset(this, 0, sizeof(*this)); } }; struct upx_compress_result_t @@ -751,7 +750,7 @@ struct upx_compress_result_t zlib_compress_result_t result_zlib; zstd_compress_result_t result_zstd; - void reset() { + void reset() noexcept { memset(&this->debug, 0, sizeof(this->debug)); result_lzma.reset(); result_ucl.reset(); result_zlib.reset(); result_zstd.reset(); } @@ -796,7 +795,7 @@ void infoWarning(const char *format, ...) attribute_format(1, 2); void infoHeader(const char *format, ...) attribute_format(1, 2); void info(const char *format, ...) attribute_format(1, 2); void infoHeader(); -void infoWriting(const char *what, long size); +void infoWriting(const char *what, upx_int64_t size); // work.cpp void do_one_file(const char *iname, char *oname); diff --git a/src/except.h b/src/except.h index 7713ba05..3445301c 100644 --- a/src/except.h +++ b/src/except.h @@ -49,12 +49,11 @@ public: private: char *msg = nullptr; int err = 0; - protected: bool is_warning = false; // can be set by subclasses private: - // disable assignment + // disable copy assignment Throwable &operator=(const Throwable &) = delete; // disable dynamic allocation => force throwing by value ACC_CXX_DISABLE_NEW_DELETE @@ -66,7 +65,6 @@ private: // Exceptions can/should be caught class Exception : public Throwable { typedef Throwable super; - public: Exception(const char *m = nullptr, int e = 0, bool w = false) noexcept : super(m, e, w) {} }; @@ -74,7 +72,6 @@ public: // Errors should not be caught (or re-thrown) class Error : public Throwable { typedef Throwable super; - public: Error(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; @@ -85,35 +82,30 @@ public: class OutOfMemoryException : public Exception { typedef Exception super; - public: OutOfMemoryException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; class IOException : public Exception { typedef Exception super; - public: IOException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; class EOFException : public IOException { typedef IOException super; - public: EOFException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; class FileNotFoundException : public IOException { typedef IOException super; - public: FileNotFoundException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; class FileAlreadyExistsException : public IOException { typedef IOException super; - public: FileAlreadyExistsException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; @@ -124,21 +116,18 @@ public: class OverlayException : public Exception { typedef Exception super; - public: OverlayException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} }; class CantPackException : public Exception { typedef Exception super; - public: CantPackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} }; class UnknownExecutableFormatException : public CantPackException { typedef CantPackException super; - public: UnknownExecutableFormatException(const char *m = nullptr, bool w = false) noexcept : super(m, w) {} @@ -146,28 +135,24 @@ public: class AlreadyPackedException : public CantPackException { typedef CantPackException super; - public: AlreadyPackedException(const char *m = nullptr) noexcept : super(m) { is_warning = true; } }; class NotCompressibleException : public CantPackException { typedef CantPackException super; - public: NotCompressibleException(const char *m = nullptr) noexcept : super(m) {} }; class CantUnpackException : public Exception { typedef Exception super; - public: CantUnpackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} }; class NotPackedException : public CantUnpackException { typedef CantUnpackException super; - public: NotPackedException(const char *m = nullptr) noexcept : super(m, true) {} }; @@ -178,7 +163,6 @@ public: class InternalError : public Error { typedef Error super; - public: InternalError(const char *m = nullptr) noexcept : super(m, 0) {} }; diff --git a/src/file.cpp b/src/file.cpp index cee8dd77..9ef1207a 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -29,10 +29,10 @@ #include "file.h" /************************************************************************* -// static functions +// static file-related util functions; will throw on error **************************************************************************/ -void FileBase::chmod(const char *name, int mode) { +/*static*/ void FileBase::chmod(const char *name, int mode) { #if (HAVE_CHMOD) if (::chmod(name, mode) != 0) throwIOException(name, errno); @@ -42,7 +42,7 @@ void FileBase::chmod(const char *name, int mode) { #endif } -void FileBase::rename(const char *old_, const char *new_) { +/*static*/ void FileBase::rename(const char *old_, const char *new_) { #if (ACC_OS_DOS32) && defined(__DJGPP__) if (::_rename(old_, new_) != 0) #else @@ -51,7 +51,7 @@ void FileBase::rename(const char *old_, const char *new_) { throwIOException("rename error", errno); } -void FileBase::unlink(const char *name) { +/*static*/ void FileBase::unlink(const char *name) { if (::unlink(name) != 0) throwIOException(name, errno); } @@ -60,11 +60,6 @@ void FileBase::unlink(const char *name) { // **************************************************************************/ -FileBase::FileBase() - : _fd(-1), _flags(0), _shflags(0), _mode(0), _name(nullptr), _offset(0), _length(0) { - memset(&st, 0, sizeof(st)); -} - FileBase::~FileBase() { #if 0 && defined(__GNUC__) // debug if (isOpen()) @@ -160,8 +155,6 @@ upx_off_t FileBase::st_size() const { return _length; } // **************************************************************************/ -InputFile::InputFile() {} - void InputFile::sopen(const char *name, int flags, int shflags) { close(); _name = name; @@ -212,8 +205,6 @@ upx_off_t InputFile::st_size_orig() const { return _length_orig; } // **************************************************************************/ -OutputFile::OutputFile() : bytes_written(0) {} - void OutputFile::sopen(const char *name, int flags, int shflags, int mode) { close(); _name = name; @@ -261,10 +252,8 @@ void OutputFile::write(SPAN_0(const void) buf, int len) { return; mem_size_assert(1, len); // sanity check errno = 0; -#if 0 - fprintf(stderr, "write %p %zd (%p) %d\n", buf.raw_ptr(), buf.raw_size_in_bytes(), - buf.raw_base(), len); -#endif + NO_fprintf(stderr, "write %p %zd (%p) %d\n", buf.raw_ptr(), buf.raw_size_in_bytes(), + buf.raw_base(), len); long l = acc_safe_hwrite(_fd, raw_bytes(buf, len), len); if (l != len) throwIOException("write error", errno); @@ -347,7 +336,7 @@ upx_off_t OutputFile::unset_extent() { return _length; } -void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int flags) { +/*static*/ void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int flags) { if (flags < 0) flags = O_CREAT | O_TRUNC; flags |= O_WRONLY | O_BINARY; @@ -357,4 +346,19 @@ void OutputFile::dump(const char *name, SPAN_P(const void) buf, int len, int fla f.closex(); } +/************************************************************************* +// +**************************************************************************/ + +TEST_CASE("file") { + InputFile fi; + CHECK(!fi.isOpen()); + CHECK(fi.getFd() == -1); + CHECK(fi.st_size() == 0); + OutputFile fo; + CHECK(!fo.isOpen()); + CHECK(fo.getFd() == -1); + CHECK(fo.getBytesWritten() == 0); +} + /* vim:set ts=4 sw=4 et: */ diff --git a/src/file.h b/src/file.h index 19203001..3f49f1de 100644 --- a/src/file.h +++ b/src/file.h @@ -33,7 +33,7 @@ class FileBase { protected: - FileBase(); + FileBase() = default; virtual ~FileBase(); public: @@ -49,7 +49,7 @@ public: virtual void set_extent(upx_off_t offset, upx_off_t length); public: - // static file-related util functions + // static file-related util functions; will throw on error static void chmod(const char *name, int mode); static void rename(const char *old_, const char *new_); static void unlink(const char *name); @@ -76,7 +76,7 @@ class InputFile final : public FileBase { typedef FileBase super; public: - InputFile(); + InputFile() = default; virtual ~InputFile() {} void sopen(const char *name, int flags, int shflags); @@ -100,7 +100,7 @@ class OutputFile final : public FileBase { typedef FileBase super; public: - OutputFile(); + OutputFile() = default; virtual ~OutputFile() {} void sopen(const char *name, int flags, int shflags, int mode); diff --git a/src/filter.cpp b/src/filter.cpp index fdacb73d..67bb06b2 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -44,7 +44,7 @@ static void initFilter(Filter *f, byte *buf, unsigned buf_len) { // get a FilterEntry **************************************************************************/ -const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) { +/*static*/ const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) { static upx_uint8_t filter_map[256]; static upx_std_once_flag init_done; @@ -69,12 +69,12 @@ const FilterImpl::FilterEntry *FilterImpl::getFilter(int id) { return &filters[index]; } -bool Filter::isValidFilter(int filter_id) { +/*static*/ bool Filter::isValidFilter(int filter_id) { const FilterImpl::FilterEntry *const fe = FilterImpl::getFilter(filter_id); return fe != nullptr; } -bool Filter::isValidFilter(int filter_id, const int *allowed_filters) { +/*static*/ bool Filter::isValidFilter(int filter_id, const int *allowed_filters) { if (!isValidFilter(filter_id)) return false; if (filter_id == 0) diff --git a/src/headers.h b/src/headers.h index df9ff9cd..90fff592 100644 --- a/src/headers.h +++ b/src/headers.h @@ -27,7 +27,7 @@ #pragma once #if !(__cplusplus + 0 >= 201703L) -#error "C++ 17 is required" +#error "C++17 is required" #endif #if !defined(_FILE_OFFSET_BITS) diff --git a/src/lefile.h b/src/lefile.h index 90767473..8d0259a0 100644 --- a/src/lefile.h +++ b/src/lefile.h @@ -222,9 +222,11 @@ protected: unsigned soentries; private: - // disable copy and assignment + // disable copy and move LeFile(const LeFile &) = delete; LeFile &operator=(const LeFile &) = delete; + LeFile(LeFile &&) = delete; + LeFile &operator=(LeFile &&) = delete; }; #endif /* already included */ diff --git a/src/msg.cpp b/src/msg.cpp index 8b6e77f4..72914452 100644 --- a/src/msg.cpp +++ b/src/msg.cpp @@ -211,10 +211,10 @@ void infoWarning(const char *format, ...) { info("[WARNING] %s\n", buf); } -void infoWriting(const char *what, long size) { +void infoWriting(const char *what, upx_int64_t size) { if (opt->info_mode <= 0) return; - info("Writing %s: %ld bytes", what, size); + info("Writing %s: %lld bytes", what, size); } /* vim:set ts=4 sw=4 et: */ diff --git a/src/options.cpp b/src/options.cpp index cc8b64a9..9072285a 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -38,7 +38,7 @@ std::mutex opt_lock_mutex; // reset **************************************************************************/ -void Options::reset() { +void Options::reset() noexcept { Options *const o = this; mem_clear(o, sizeof(*o)); o->crp.reset(); diff --git a/src/options.h b/src/options.h index e58634c5..35030722 100644 --- a/src/options.h +++ b/src/options.h @@ -110,7 +110,7 @@ struct Options final { ucl_compress_config_t crp_ucl; zlib_compress_config_t crp_zlib; zstd_compress_config_t crp_zstd; - void reset() { + void reset() noexcept { crp_lzma.reset(); crp_ucl.reset(); crp_zlib.reset(); @@ -169,7 +169,7 @@ struct Options final { const char *keep_resource; } win32_pe; - void reset(); + void reset() noexcept; }; /* vim:set ts=4 sw=4 et: */ diff --git a/src/p_tos.h b/src/p_tos.h index 23990703..b1cee6fb 100644 --- a/src/p_tos.h +++ b/src/p_tos.h @@ -99,7 +99,7 @@ protected: unsigned clear_dirty_stack_len; unsigned copy_to_stack_len; - void reset() { memset(this, 0, sizeof(*this)); } + void reset() noexcept { memset(this, 0, sizeof(*this)); } }; LinkerSymbols symbols; }; diff --git a/src/packer.cpp b/src/packer.cpp index 196f4516..f3f1329e 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -501,7 +501,7 @@ unsigned Packer::findOverlapOverhead(const byte *buf, const byte *tbuf, unsigned // file i/o utils **************************************************************************/ -void Packer::handleStub(InputFile *fif, OutputFile *fo, unsigned size) { +/*static*/ void Packer::handleStub(InputFile *fif, OutputFile *fo, unsigned size) { if (fo) { if (size > 0) { // copy stub from exe diff --git a/src/packer.h b/src/packer.h index 8214643c..55daaebf 100644 --- a/src/packer.h +++ b/src/packer.h @@ -329,9 +329,9 @@ protected: upx_uint64_t file_size_u; // explicitly unsigned }; - PackHeader ph; // must be filled by canUnpack() - int ph_format; - int ph_version; + PackHeader ph = {}; // must be filled by canUnpack() + int ph_format = 0; + int ph_version = 0; // compression buffers MemBuffer ibuf; // input @@ -347,13 +347,15 @@ protected: private: // private to checkPatch() void *last_patch = nullptr; - int last_patch_len; - int last_patch_off; + int last_patch_len = 0; + int last_patch_off = 0; private: - // disable copy and assignment + // disable copy and move Packer(const Packer &) = delete; Packer &operator=(const Packer &) = delete; + Packer(Packer &&) = delete; + Packer &operator=(Packer &&) = delete; }; int force_method(int method); // (0x80ul<<24)|method diff --git a/src/packer_c.cpp b/src/packer_c.cpp index 28146aa5..a905cb9c 100644 --- a/src/packer_c.cpp +++ b/src/packer_c.cpp @@ -33,7 +33,7 @@ // compression method util **************************************************************************/ -bool Packer::isValidCompressionMethod(int method) +/*static*/ bool Packer::isValidCompressionMethod(int method) { if (M_IS_LZMA(method)) return true; diff --git a/src/packer_r.cpp b/src/packer_r.cpp index 1260622e..dfc8cb00 100644 --- a/src/packer_r.cpp +++ b/src/packer_r.cpp @@ -33,6 +33,7 @@ // returns number of bytes written to 'out' **************************************************************************/ +/*static*/ unsigned Packer::optimizeReloc(unsigned relocnum, SPAN_P(byte) relocs, SPAN_S(byte) out, SPAN_P(byte) image, unsigned image_size, int bits, bool bswap, int *big) { @@ -92,6 +93,7 @@ unsigned Packer::optimizeReloc(unsigned relocnum, SPAN_P(byte) relocs, SPAN_S(by // allocates 'out' and returns number of relocs written to 'out' **************************************************************************/ +/*static*/ unsigned Packer::unoptimizeReloc(SPAN_S(const byte) & in, MemBuffer &out, SPAN_P(byte) image, unsigned image_size, int bits, bool bswap) { assert(bits == 32 || bits == 64); diff --git a/src/packhead.cpp b/src/packhead.cpp index 5f631387..8c8ca279 100644 --- a/src/packhead.cpp +++ b/src/packhead.cpp @@ -38,17 +38,17 @@ PackHeader::PackHeader() : version(-1), format(-1) {} /************************************************************************* -// simple checksum for the header itself (since version 10) +// very simple checksum for the header itself (since version 10) **************************************************************************/ -static byte get_packheader_checksum(SPAN_S(const byte) buf, int len) { - assert(len >= 4); +static byte get_packheader_checksum(SPAN_S(const byte) buf, int blen) { + assert(blen >= 4); assert(get_le32(buf) == UPX_MAGIC_LE32); - // printf("1 %d\n", len); + // printf("1 %d\n", blen); buf += 4; - len -= 4; + blen -= 4; unsigned c = 0; - while (len-- > 0) + while (blen-- > 0) c += *buf++; c %= 251; // printf("2 %d\n", c); diff --git a/src/pefile.h b/src/pefile.h index e932363c..b858dd1d 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -99,9 +99,9 @@ protected: MemBuffer mb_oimport; SPAN_0(byte) oimport = nullptr; unsigned soimport; - byte *oimpdlls; + byte *oimpdlls = nullptr; unsigned soimpdlls; - ImportLinker *ilinker; + ImportLinker *ilinker = nullptr; virtual const char *kernelDll() const { return "KERNEL32.DLL"; } void addKernelImport(const char *); virtual void addStubImports(); diff --git a/src/ui.cpp b/src/ui.cpp index 096fbb4f..e6e7634b 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -352,6 +352,7 @@ void UiPacker::endCallback(bool done) { // the callback **************************************************************************/ +/*static*/ void __acc_cdecl UiPacker::progress_callback(upx_callback_p cb, unsigned isize, unsigned osize) { // printf("%6d %6d %d\n", isize, osize, state); UiPacker *self = (UiPacker *) cb->user; @@ -471,7 +472,7 @@ void UiPacker::uiPackEnd(const OutputFile *fo) { printSetNl(0); } -void UiPacker::uiPackTotal() { +/*static*/ void UiPacker::uiPackTotal() { uiListTotal(); uiFooter("Packed"); } @@ -502,7 +503,7 @@ void UiPacker::uiUnpackEnd(const OutputFile *fo) { printSetNl(0); } -void UiPacker::uiUnpackTotal() { +/*static*/ void UiPacker::uiUnpackTotal() { uiListTotal(true); uiFooter("Unpacked"); } @@ -523,7 +524,7 @@ void UiPacker::uiList() { void UiPacker::uiListEnd() { uiUpdate(); } -void UiPacker::uiListTotal(bool decompress) { +/*static*/ void UiPacker::uiListTotal(bool decompress) { if (opt->verbose >= 1 && total_files >= 2) { char name[32]; upx_safe_snprintf(name, sizeof(name), "[ %u file%s ]", total_files_done, @@ -558,7 +559,7 @@ void UiPacker::uiTestEnd() { uiUpdate(); } -void UiPacker::uiTestTotal() { uiFooter("Tested"); } +/*static*/ void UiPacker::uiTestTotal() { uiFooter("Tested"); } /************************************************************************* // info @@ -585,14 +586,14 @@ bool UiPacker::uiFileInfoStart() { void UiPacker::uiFileInfoEnd() { uiUpdate(); } -void UiPacker::uiFileInfoTotal() {} +/*static*/ void UiPacker::uiFileInfoTotal() {} /************************************************************************* // util **************************************************************************/ -void UiPacker::uiHeader() { - static bool done = false; +/*static*/ void UiPacker::uiHeader() { + static upx_std_atomic(bool) done; if (done) return; done = true; @@ -603,8 +604,8 @@ void UiPacker::uiHeader() { } } -void UiPacker::uiFooter(const char *t) { - static bool done = false; +/*static*/ void UiPacker::uiFooter(const char *t) { + static upx_std_atomic(bool) done; if (done) return; done = true; @@ -628,7 +629,7 @@ void UiPacker::uiUpdate(upx_off_t fc_len, upx_off_t fu_len) { update_u_len = p->ph.u_len; } -void UiPacker::uiConfirmUpdate() { +/*static*/ void UiPacker::uiConfirmUpdate() { total_files_done++; total_fc_len += update_fc_len; total_fu_len += update_fu_len; diff --git a/src/ui.h b/src/ui.h index b204bf3e..cff70a5e 100644 --- a/src/ui.h +++ b/src/ui.h @@ -79,15 +79,15 @@ public: static void uiHeader(); static void uiFooter(const char *n); - int ui_pass; - int ui_total_passes; + int ui_pass = 0; + int ui_total_passes = 0; protected: virtual void printInfo(int nl = 0); const Packer *p = nullptr; // callback - upx_callback_t cb; + upx_callback_t cb = {}; // internal state struct State; diff --git a/src/util/membuffer.h b/src/util/membuffer.h index 4dfeb3a2..4390bf5b 100644 --- a/src/util/membuffer.h +++ b/src/util/membuffer.h @@ -130,7 +130,7 @@ inline typename MemBufferBase::pointer raw_index_bytes(const MemBufferBase #undef XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION /************************************************************************* -// +// MemBuffer **************************************************************************/ class MemBuffer final : public MemBufferBase { @@ -185,7 +185,7 @@ private: void *last_return_address_dealloc; void *last_return_address_fill; void *last_return_address_subref; - Debug() { memset(this, 0, sizeof(*this)); } + Debug() noexcept { memset(this, 0, sizeof(*this)); } }; Debug debug; #endif diff --git a/src/util/snprintf.h b/src/util/snprintf.h index eeb69477..33d25b9b 100644 --- a/src/util/snprintf.h +++ b/src/util/snprintf.h @@ -26,8 +26,6 @@ */ #pragma once -#ifndef UPX_SNPRINTF_H__ -#define UPX_SNPRINTF_H__ 1 /************************************************************************* // UPX version of string functions, with assertions and sane limits @@ -87,6 +85,4 @@ forceinline upx_rsize_t upx_safe_strlen(const uchar *s) { return upx_safe_strlen((const char *) s); } -#endif /* already included */ - /* vim:set ts=4 sw=4 et: */ diff --git a/src/util/util.cpp b/src/util/util.cpp index 5e4e530b..6c003278 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -445,7 +445,7 @@ int __acc_cdecl_qsort le64_compare_signed(const void *e1, const void *e2) { // find and mem_replace util **************************************************************************/ -int find(const void *buf, int blen, const void *what, int wlen) { +int find(const void *buf, int blen, const void *what, int wlen) noexcept { // nullptr is explicitly allowed here if (buf == nullptr || blen < wlen || what == nullptr || wlen <= 0) return -1; @@ -461,37 +461,37 @@ int find(const void *buf, int blen, const void *what, int wlen) { return -1; } -int find_be16(const void *b, int blen, unsigned what) { +int find_be16(const void *b, int blen, unsigned what) noexcept { byte w[2]; set_be16(w, what); return find(b, blen, w, 2); } -int find_be32(const void *b, int blen, unsigned what) { +int find_be32(const void *b, int blen, unsigned what) noexcept { byte w[4]; set_be32(w, what); return find(b, blen, w, 4); } -int find_be64(const void *b, int blen, upx_uint64_t what) { +int find_be64(const void *b, int blen, upx_uint64_t what) noexcept { byte w[8]; set_be64(w, what); return find(b, blen, w, 8); } -int find_le16(const void *b, int blen, unsigned what) { +int find_le16(const void *b, int blen, unsigned what) noexcept { byte w[2]; set_le16(w, what); return find(b, blen, w, 2); } -int find_le32(const void *b, int blen, unsigned what) { +int find_le32(const void *b, int blen, unsigned what) noexcept { byte w[4]; set_le32(w, what); return find(b, blen, w, 4); } -int find_le64(const void *b, int blen, upx_uint64_t what) { +int find_le64(const void *b, int blen, upx_uint64_t what) noexcept { byte w[8]; set_le64(w, what); return find(b, blen, w, 8); @@ -518,7 +518,7 @@ TEST_CASE("find") { CHECK(find_le64(b, 15, 0x0f0e0d0c0b0a0908ULL) == -1); } -int mem_replace(void *buf, int blen, const void *what, int wlen, const void *replacement) { +int mem_replace(void *buf, int blen, const void *what, int wlen, const void *replacement) noexcept { byte *b = (byte *) buf; int boff = 0; int n = 0; diff --git a/src/util/util.h b/src/util/util.h index e1511e6b..9e6d0518 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -26,8 +26,6 @@ */ #pragma once -#ifndef UPX_UTIL_H__ -#define UPX_UTIL_H__ 1 /************************************************************************* // assert sane memory buffer sizes to protect against integer overflows @@ -80,13 +78,13 @@ template T *NewArray(upx_uint64_t n) { size_t bytes = mem_size(sizeof(T), n); // assert size T *array = new T[size_t(n)]; - if (array) { + if (array != nullptr && bytes > 0) { memset(array, 0xfb, bytes); (void) VALGRIND_MAKE_MEM_UNDEFINED(array, bytes); } return array; } -#define New(type, n) (NewArray(n)) +#define New(type, n) (NewArray((n))) #else #define New(type, n) new type[mem_size_get_n(sizeof(type), (n))] #endif @@ -142,15 +140,15 @@ void upx_stable_sort(void *array, size_t n, size_t element_size, // 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 find(const void *b, int blen, const void *what, int wlen) noexcept; +int find_be16(const void *b, int blen, unsigned what) noexcept; +int find_be32(const void *b, int blen, unsigned what) noexcept; +int find_be64(const void *b, int blen, upx_uint64_t what) noexcept; +int find_le16(const void *b, int blen, unsigned what) noexcept; +int find_le32(const void *b, int blen, unsigned what) noexcept; +int find_le64(const void *b, int blen, upx_uint64_t what) noexcept; -int mem_replace(void *b, int blen, const void *what, int wlen, const void *r); +int mem_replace(void *b, int blen, const void *what, int wlen, const void *r) noexcept; char *fn_basename(const char *name); int fn_strcmp(const char *n1, const char *n2); @@ -166,6 +164,4 @@ 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); -#endif /* already included */ - /* vim:set ts=4 sw=4 et: */