From 828f4a63bfffb8c0e555748029b7d6e31e2c9087 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Sun, 16 Jul 2023 07:37:31 +0200 Subject: [PATCH] src: add some "explicit"; cleanups --- .clang-format | 1 + .github/workflows/ci.yml | 13 +++++--- CMakeLists.txt | 13 ++++++-- compile_flags.txt | 1 + misc/rebuild-stubs-with-podman/Dockerfile | 2 +- src/bele_policy.h | 30 +++++++++--------- src/conf.h | 37 ++++++++++++++++++----- src/except.h | 36 +++++++++++----------- src/file.cpp | 26 ++++++++-------- src/file.h | 20 ++++++------ src/filter.cpp | 8 +++-- src/filter.h | 11 +++---- src/help.cpp | 12 ++++---- src/lefile.cpp | 11 ++++--- src/lefile.h | 36 +++++++++++----------- src/linker.h | 21 +++++++------ src/p_com.h | 2 +- src/p_djgpp2.cpp | 2 +- src/p_djgpp2.h | 2 +- src/p_exe.h | 6 ++-- src/p_ps1.h | 2 +- src/p_sys.h | 2 +- src/p_tmt.cpp | 10 +++--- src/p_tmt.h | 2 +- src/p_tos.h | 2 +- src/p_w32pe_i386.h | 2 +- src/p_w64pe_amd64.h | 2 +- src/p_w64pe_arm64.h | 4 +-- src/p_wcle.cpp | 4 +-- src/p_wcle.h | 8 ++--- src/p_wince_arm.h | 2 +- src/packer.cpp | 16 +++++----- src/packer.h | 22 +++++++------- src/packmast.cpp | 3 +- src/packmast.h | 6 ++-- src/pefile.cpp | 10 +++--- src/pefile.h | 22 ++++++-------- src/ui.cpp | 4 +-- src/ui.h | 6 ++-- src/util/membuffer.h | 4 +-- src/util/util.cpp | 8 ++--- src/util/xspan.h | 2 +- src/util/xspan_impl_common.h | 6 ++-- 43 files changed, 238 insertions(+), 201 deletions(-) diff --git a/.clang-format b/.clang-format index 7b107654..ac568fac 100644 --- a/.clang-format +++ b/.clang-format @@ -21,6 +21,7 @@ AttributeMacros: - DELETED_FUNCTION - XSPAN_DELETED_FUNCTION - forceinline + - may_throw - noinline - static_forceinline - static_noinline diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 497dd9c6..60e7f2fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,11 +22,16 @@ jobs: - name: 'Install extra packages' run: | uname -a; pwd; id; umask - if ! test -e /usr/bin/python2; then - sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal - fi mkdir ../deps; cd ../deps; mkdir packages - # manually install compat libs from Ubuntu 16.04 + if ! test -e /usr/bin/python2; then + ####sudo apt-get update && sudo apt-get install -y --no-install-recommends python2-minimal + # install python2-minimal packages from Debian-11 + wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/libpython2.7-minimal_2.7.18-8_amd64.deb' + wget -q 'https://ftp.debian.org/debian/pool/main/p/python2.7/python2.7-minimal_2.7.18-8_amd64.deb' + sudo dpkg -i ./*python2*.deb && rm ./*python2*.deb && sudo ldconfig + sudo ln -s -v python2.7 /usr/bin/python2 + fi + # manually unpack and install compat libs from Ubuntu-16.04 wget -q 'https://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb' for f in ./*.deb; do dpkg -x $f ./packages; done sudo mv -v -n ./packages/usr/lib/x86_64-linux-gnu/lib* /usr/lib/x86_64-linux-gnu/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 44b5b942..e3849744 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,12 @@ endif() # common compilation flags #*********************************************************************** +include(CheckCCompilerFlag) +if(CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") + check_c_compiler_flag(-fno-delete-null-pointer-checks HAVE_CFLAG_FNO_DELETE_NULL_POINTER_CHECKS) + check_c_compiler_flag(-fno-lifetime-dse HAVE_CFLAG_FNO_LIFETIME_DSE) +endif() + if(UPX_CONFIG_DISABLE_WSTRICT) # enable all basic warnings set(warn_Wall -Wall) @@ -167,8 +173,11 @@ if(MSVC_FRONTEND) add_definitions(-J -Zc:__cplusplus -Zc:preprocessor) else() # protect against security threats caused by misguided compiler "optimizations" - if(CMAKE_C_COMPILER_ID STREQUAL "GNU") - add_definitions(-fno-delete-null-pointer-checks -fno-lifetime-dse) + if(HAVE_CFLAG_FNO_DELETE_NULL_POINTER_CHECKS) + add_definitions(-fno-delete-null-pointer-checks) + endif() + if(HAVE_CFLAG_FNO_LIFETIME_DSE) + add_definitions(-fno-lifetime-dse) endif() add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char) # disable overambitious auto-vectorization until this actually gains something diff --git a/compile_flags.txt b/compile_flags.txt index 486ef41c..0b508e35 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -1,5 +1,6 @@ -std=gnu++17 -Ivendor +-DDEBUG -fno-strict-aliasing -fno-strict-overflow -funsigned-char diff --git a/misc/rebuild-stubs-with-podman/Dockerfile b/misc/rebuild-stubs-with-podman/Dockerfile index 4e3a0cd5..c9ff96b1 100644 --- a/misc/rebuild-stubs-with-podman/Dockerfile +++ b/misc/rebuild-stubs-with-podman/Dockerfile @@ -21,7 +21,7 @@ RUN dpkg --add-architecture i386 \ g++-multilib gcc-multilib \ && true -# manually install compat libs from Ubuntu 16.04; REQUIRED +# manually unpack and install compat libs from Ubuntu-16.04; REQUIRED RUN cd /root \ && aria2c --checksum=sha-256=de22baf3dd851a10e16fbf66a243e70149ca46e06b2939fdc79429196cefc090 \ 'https://archive.kernel.org/ubuntu-archive/ubuntu/pool/main/m/mpfr4/libmpfr4_3.1.6-1_amd64.deb' \ diff --git a/src/bele_policy.h b/src/bele_policy.h index dd645ae1..f147be4c 100644 --- a/src/bele_policy.h +++ b/src/bele_policy.h @@ -47,7 +47,7 @@ #if defined(BELE_RTP) struct AbstractPolicy { - inline AbstractPolicy() noexcept {} + explicit inline AbstractPolicy() noexcept {} virtual inline ~AbstractPolicy() noexcept {} V bool isBE() C = 0; V bool isLE() C = 0; @@ -79,10 +79,10 @@ struct AbstractPolicy { private: // disable copy and move - AbstractPolicy(const AbstractPolicy &) = delete; - AbstractPolicy &operator=(const AbstractPolicy &) = delete; - AbstractPolicy(AbstractPolicy &&) noexcept = delete; - AbstractPolicy &operator=(AbstractPolicy &&) noexcept = delete; + AbstractPolicy(const AbstractPolicy &) DELETED_FUNCTION; + AbstractPolicy &operator=(const AbstractPolicy &) DELETED_FUNCTION; + AbstractPolicy(AbstractPolicy &&) noexcept DELETED_FUNCTION; + AbstractPolicy &operator=(AbstractPolicy &&) noexcept DELETED_FUNCTION; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE }; @@ -98,7 +98,7 @@ struct BEPolicy final : public AbstractPolicy #endif { - inline BEPolicy() noexcept {} + explicit inline BEPolicy() noexcept {} #if defined(BELE_CTP) typedef N_BELE_RTP::BEPolicy RTP_Policy; #elif defined(BELE_RTP) @@ -147,10 +147,10 @@ struct BEPolicy private: // disable copy and move - BEPolicy(const BEPolicy &) = delete; - BEPolicy &operator=(const BEPolicy &) = delete; - BEPolicy(BEPolicy &&) noexcept = delete; - BEPolicy &operator=(BEPolicy &&) noexcept = delete; + BEPolicy(const BEPolicy &) DELETED_FUNCTION; + BEPolicy &operator=(const BEPolicy &) DELETED_FUNCTION; + BEPolicy(BEPolicy &&) noexcept DELETED_FUNCTION; + BEPolicy &operator=(BEPolicy &&) noexcept DELETED_FUNCTION; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE }; @@ -160,7 +160,7 @@ struct LEPolicy final : public AbstractPolicy #endif { - inline LEPolicy() noexcept {} + explicit inline LEPolicy() noexcept {} #if defined(BELE_CTP) typedef N_BELE_RTP::LEPolicy RTP_Policy; #elif defined(BELE_RTP) @@ -209,10 +209,10 @@ struct LEPolicy private: // disable copy and move - LEPolicy(const LEPolicy &) = delete; - LEPolicy &operator=(const LEPolicy &) = delete; - LEPolicy(LEPolicy &&) noexcept = delete; - LEPolicy &operator=(LEPolicy &&) noexcept = delete; + LEPolicy(const LEPolicy &) DELETED_FUNCTION; + LEPolicy &operator=(const LEPolicy &) DELETED_FUNCTION; + LEPolicy(LEPolicy &&) noexcept DELETED_FUNCTION; + LEPolicy &operator=(LEPolicy &&) noexcept DELETED_FUNCTION; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE }; diff --git a/src/conf.h b/src/conf.h index 914d4125..e20b2704 100644 --- a/src/conf.h +++ b/src/conf.h @@ -155,7 +155,7 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1) typedef upx_int64_t upx_off_t; #undef off_t #if 0 -// TODO cleanup: at some future point we can do this... +// TODO cleanup: at some future point we can do this: #define off_t DO_NOT_USE_off_t #else #define off_t upx_off_t @@ -174,6 +174,7 @@ typedef upx_int64_t upx_off_t; #define unlikely __acc_unlikely #define very_likely __acc_very_likely #define very_unlikely __acc_very_unlikely +#define may_throw noexcept(false) #define COMPILE_TIME_ASSERT(e) ACC_COMPILE_TIME_ASSERT(e) #define DELETED_FUNCTION = delete @@ -318,10 +319,10 @@ typedef upx_int64_t upx_off_t; #endif // for no-op debug output -inline void NO_printf(const char *, ...) attribute_format(1, 2); -inline void NO_fprintf(FILE *, const char *, ...) attribute_format(2, 3); -inline void NO_printf(const char *, ...) {} -inline void NO_fprintf(FILE *, const char *, ...) {} +inline void NO_printf(const char *, ...) noexcept attribute_format(1, 2); +inline void NO_fprintf(FILE *, const char *, ...) noexcept attribute_format(2, 3); +inline void NO_printf(const char *, ...) noexcept {} +inline void NO_fprintf(FILE *, const char *, ...) noexcept {} #if !defined(__has_builtin) # define __has_builtin(x) 0 @@ -385,6 +386,26 @@ struct UnsignedSizeOf { }; #define usizeof(expr) (UnsignedSizeOf::value) +// simple pointer type alias to explicitly mark ownership of objects; purely +// cosmetic to improve source code readability, no real functionality +#if 0 +#define OwningPointer(T) T * +#else +template using OwningPointer = T *; +#define OwningPointer(T) OwningPointer +#endif +template +inline void owner_delete(OwningPointer(T) (&object)) noexcept { + static_assert(std::is_class_v); + static_assert(std::is_nothrow_destructible_v); + delete object; + object = nullptr; +} +template +inline void owner_delete(T (&array)[]) noexcept DELETED_FUNCTION; +template +inline void owner_delete(T (&array)[N]) noexcept DELETED_FUNCTION; + template inline void mem_clear(T *object) noexcept { static_assert(std::is_class_v); @@ -395,9 +416,9 @@ inline void mem_clear(T *object) noexcept { memset((void *) object, 0, size); } template -inline void mem_clear(T (&array)[]) noexcept = delete; +inline void mem_clear(T (&array)[]) noexcept DELETED_FUNCTION; template -inline void mem_clear(T (&array)[N]) noexcept = delete; +inline void mem_clear(T (&array)[N]) noexcept DELETED_FUNCTION; // An Array allocates memory on the heap, and automatically // gets destructed when leaving scope or on exceptions. @@ -630,7 +651,7 @@ struct upx_callback_t { **************************************************************************/ template -struct OptVar { +struct OptVar final { static_assert(std::is_integral_v); typedef T value_type; static constexpr T default_value = default_value_; diff --git a/src/except.h b/src/except.h index 63151ea9..f8e59f1b 100644 --- a/src/except.h +++ b/src/except.h @@ -56,13 +56,15 @@ protected: bool is_warning = false; // can be set by subclasses private: - // disable copy assignment - Throwable &operator=(const Throwable &) = delete; + // disable copy assignment and move + Throwable &operator=(const Throwable &) DELETED_FUNCTION; + Throwable(Throwable &&) noexcept DELETED_FUNCTION; + Throwable &operator=(Throwable &&) noexcept DELETED_FUNCTION; // disable dynamic allocation => force throwing by value ACC_CXX_DISABLE_NEW_DELETE // disable taking the address => force passing by reference // [I'm not too sure about this design decision, but we can always allow it if needed] - Throwable *operator&() const noexcept = delete; + Throwable *operator&() const noexcept DELETED_FUNCTION; private: static upx_std_atomic(size_t) debug_counter; // for debugging @@ -86,31 +88,31 @@ public: // system exception **************************************************************************/ -class OutOfMemoryException : public Exception { +class OutOfMemoryException final : public Exception { typedef Exception super; public: OutOfMemoryException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; -class IOException : public Exception { +class IOException /*not_final*/ : public Exception { typedef Exception super; public: IOException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; -class EOFException : public IOException { +class EOFException final : public IOException { typedef IOException super; public: EOFException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; -class FileNotFoundException : public IOException { +class FileNotFoundException final : public IOException { typedef IOException super; public: FileNotFoundException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} }; -class FileAlreadyExistsException : public IOException { +class FileAlreadyExistsException final : public IOException { typedef IOException super; public: FileAlreadyExistsException(const char *m = nullptr, int e = 0) noexcept : super(m, e) {} @@ -120,13 +122,13 @@ public: // application exceptions **************************************************************************/ -class OverlayException : public Exception { +class OverlayException final : public Exception { typedef Exception super; public: OverlayException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} }; -class CantPackException : public Exception { +class CantPackException /*not_final*/ : public Exception { typedef Exception super; public: CantPackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} @@ -139,25 +141,25 @@ public: : super(m, w) {} }; -class AlreadyPackedException : public CantPackException { +class AlreadyPackedException final : public CantPackException { typedef CantPackException super; public: AlreadyPackedException(const char *m = nullptr) noexcept : super(m) { is_warning = true; } }; -class NotCompressibleException : public CantPackException { +class NotCompressibleException final : public CantPackException { typedef CantPackException super; public: NotCompressibleException(const char *m = nullptr) noexcept : super(m) {} }; -class CantUnpackException : public Exception { +class CantUnpackException /*not_final*/ : public Exception { typedef Exception super; public: CantUnpackException(const char *m = nullptr, bool w = false) noexcept : super(m, 0, w) {} }; -class NotPackedException : public CantUnpackException { +class NotPackedException final : public CantUnpackException { typedef CantUnpackException super; public: NotPackedException(const char *m = nullptr) noexcept : super(m, true) {} @@ -167,7 +169,7 @@ public: // errors **************************************************************************/ -class InternalError : public Error { +class InternalError final : public Error { typedef Error super; public: InternalError(const char *m = nullptr) noexcept : super(m, 0) {} @@ -203,11 +205,11 @@ NORET void throwEOFException(const char *msg = nullptr, int e = 0); // some C++ template wizardry is needed to overload throwCantPack() for varargs template -void throwCantPack(const T *, ...) = delete; +void throwCantPack(const T *, ...) DELETED_FUNCTION; template <> NORET void throwCantPack(const char *format, ...) attribute_format(1, 2); template -void throwCantUnpack(const T *, ...) = delete; +void throwCantUnpack(const T *, ...) DELETED_FUNCTION; template <> NORET void throwCantUnpack(const char *format, ...) attribute_format(1, 2); diff --git a/src/file.cpp b/src/file.cpp index c6775c8a..e1072957 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -60,7 +60,7 @@ // **************************************************************************/ -FileBase::~FileBase() { +FileBase::~FileBase() may_throw { #if 0 && defined(__GNUC__) // debug if (isOpen()) fprintf(stderr,"%s: %s\n", _name, __PRETTY_FUNCTION__); @@ -107,7 +107,7 @@ bool FileBase::close() noexcept { return ok; } -void FileBase::closex() { +void FileBase::closex() may_throw { if (!close()) throwIOException("close failed", errno); } @@ -174,10 +174,10 @@ void InputFile::sopen(const char *name, int flags, int shflags) { _length_orig = _length; } -int InputFile::read(SPAN_P(void) buf, int len) { - if (!isOpen() || len < 0) +int InputFile::read(SPAN_P(void) buf, upx_int64_t blen) { + if (!isOpen() || blen < 0) throwIOException("bad read"); - mem_size_assert(1, len); // sanity check + int len = (int) mem_size(1, blen); // sanity check errno = 0; long l = acc_safe_hread(_fd, raw_bytes(buf, len), len); if (errno) @@ -185,9 +185,9 @@ int InputFile::read(SPAN_P(void) buf, int len) { return (int) l; } -int InputFile::readx(SPAN_P(void) buf, int len) { - int l = this->read(buf, len); - if (l != len) +int InputFile::readx(SPAN_P(void) buf, upx_int64_t blen) { + int l = this->read(buf, blen); + if (l != blen) throwEOFException(); return l; } @@ -244,13 +244,13 @@ bool OutputFile::openStdout(int flags, bool force) { return true; } -void OutputFile::write(SPAN_0(const void) buf, int len) { - if (!isOpen() || len < 0) +void OutputFile::write(SPAN_0(const void) buf, upx_int64_t blen) { + if (!isOpen() || blen < 0) throwIOException("bad write"); - // allow nullptr if len == 0 - if (len == 0) + // allow nullptr if blen == 0 + if (blen == 0) return; - mem_size_assert(1, len); // sanity check + int len = (int) mem_size(1, blen); // sanity check errno = 0; #if WITH_XSPAN >= 2 NO_fprintf(stderr, "write %p %zd (%p) %d\n", buf.raw_ptr(), buf.raw_size_in_bytes(), diff --git a/src/file.h b/src/file.h index 86b3d73c..5665e2d2 100644 --- a/src/file.h +++ b/src/file.h @@ -33,12 +33,12 @@ class FileBase { protected: - FileBase() = default; - virtual ~FileBase(); + explicit FileBase() noexcept = default; + virtual ~FileBase() may_throw; public: bool close() noexcept; - void closex(); + void closex() may_throw; bool isOpen() const { return _fd >= 0; } int getFd() const { return _fd; } const char *getName() const { return _name; } @@ -76,13 +76,13 @@ class InputFile final : public FileBase { typedef FileBase super; public: - InputFile() = default; + explicit InputFile() noexcept = default; void sopen(const char *name, int flags, int shflags); void open(const char *name, int flags) { sopen(name, flags, -1); } - int read(SPAN_P(void) buf, int len); - int readx(SPAN_P(void) buf, int len); + int read(SPAN_P(void) buf, upx_int64_t blen); + int readx(SPAN_P(void) buf, upx_int64_t blen); virtual upx_off_t seek(upx_off_t off, int whence) override; upx_off_t st_size_orig() const; @@ -99,14 +99,14 @@ class OutputFile final : public FileBase { typedef FileBase super; public: - OutputFile() = default; + explicit OutputFile() noexcept = default; void sopen(const char *name, int flags, int shflags, int mode); void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); } bool openStdout(int flags = 0, bool force = false); - // info: allow nullptr if len == 0 - void write(SPAN_0(const void) buf, int len); + // info: allow nullptr if blen == 0 + void write(SPAN_0(const void) buf, upx_int64_t blen); virtual upx_off_t seek(upx_off_t off, int whence) override; virtual upx_off_t st_size() const override; // { return _length; } @@ -115,7 +115,7 @@ public: upx_off_t getBytesWritten() const { return bytes_written; } - // FIXME - these won't work when using the '--stdout' option + // FIXME - this won't work when using the '--stdout' option void rewrite(SPAN_P(const void) buf, int len); // util diff --git a/src/filter.cpp b/src/filter.cpp index 46562172..a5e6c8da 100644 --- a/src/filter.cpp +++ b/src/filter.cpp @@ -33,7 +33,7 @@ // util **************************************************************************/ -static void initFilter(Filter *f, byte *buf, unsigned buf_len) { +static void initFilter(Filter *f, byte *buf, unsigned buf_len) noexcept { f->buf = buf; f->buf_len = buf_len; // clear output parameters @@ -65,7 +65,7 @@ static void initFilter(Filter *f, byte *buf, unsigned buf_len) { unsigned index = filter_map[id]; if (index == 0xff) // empty slot return nullptr; - assert(filters[index].id == id); + assert_noexcept(filters[index].id == id); return &filters[index]; } @@ -91,7 +91,9 @@ static void initFilter(Filter *f, byte *buf, unsigned buf_len) { // high level API **************************************************************************/ -void Filter::init(int id_, unsigned addvalue_) { +Filter::Filter(int level) noexcept : clevel(level) { init(); } + +void Filter::init(int id_, unsigned addvalue_) noexcept { this->id = id_; initFilter(this, nullptr, 0); // clear input parameters diff --git a/src/filter.h b/src/filter.h index 2496b715..cb826d89 100644 --- a/src/filter.h +++ b/src/filter.h @@ -44,13 +44,10 @@ // to absolute addresses so that the buffer compresses better. **************************************************************************/ -class Filter { +class Filter final { public: - Filter(int level) { - clevel = level; - init(); - } - void init(int id = 0, unsigned addvalue = 0); + explicit Filter(int level) noexcept; + void init(int id = 0, unsigned addvalue = 0) noexcept; bool filter(SPAN_0(byte) buf, unsigned buf_len); void unfilter(SPAN_0(byte) buf, unsigned buf_len, bool verify_checksum = false); @@ -103,6 +100,8 @@ class FilterImpl { friend class Filter; private: + explicit FilterImpl() noexcept DELETED_FUNCTION; + struct FilterEntry { int id; // 0 .. 255 unsigned min_buf_len; diff --git a/src/help.cpp b/src/help.cpp index 2424d4ac..69587ccb 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -103,16 +103,16 @@ struct PackerNames { size_t names_count; const Options *o; PackerNames() : names_count(0), o(nullptr) {} - void add(const Packer *p) { + void add(const Packer *packer) { assert(names_count < 64); - names[names_count].fname = p->getFullName(o); - names[names_count].sname = p->getName(); + names[names_count].fname = packer->getFullName(o); + names[names_count].sname = packer->getName(); names_count++; } - static Packer *visit(Packer *p, void *user) { + static Packer *visit(Packer *packer, void *user) { PackerNames *self = (PackerNames *) user; - self->add(p); - delete p; + self->add(packer); + delete packer; return nullptr; } static int __acc_cdecl_qsort cmp_fname(const void *a, const void *b) { diff --git a/src/lefile.cpp b/src/lefile.cpp index 845fe9f3..a1508407 100644 --- a/src/lefile.cpp +++ b/src/lefile.cpp @@ -27,10 +27,9 @@ #include "conf.h" #include "file.h" -#include "util/membuffer.h" #include "lefile.h" -LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) { +LeFile::LeFile(InputFile *f) noexcept : fif(f) { 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) @@ -159,7 +158,7 @@ void LeFile::readImage() { (ipm_entries[ic].m * 0x100 + ipm_entries[ic].l - 1) * mps, SEEK_SET); auto bytes = ic != pages - 1 ? mps : ih.bytes_on_last_page; - fif->readx(raw_bytes(iimage + jc, bytes), bytes); + fif->readx(iimage + jc, bytes); } jc += mps; } @@ -167,7 +166,7 @@ void LeFile::readImage() { void LeFile::writeImage() { if (fof && oimage != nullptr) - fof->write(raw_bytes(oimage, soimage), soimage); + fof->write(oimage, soimage); } void LeFile::readNonResidentNames() { @@ -219,7 +218,9 @@ bool LeFile::readFileHeader() { return false; fif->seek(le_offset, SEEK_SET); fif->readx(&ih, sizeof(ih)); - if (mps < 512 || mps > 2097152 || (mps & (mps - 1)) != 0 || ih.bytes_on_last_page > mps) + if (mps < 512 || mps > 2097152 || (mps & (mps - 1)) != 0) + throwCantPack("file header invalid page size"); + if (ih.bytes_on_last_page > mps || pages == 0) throwCantPack("bad file header"); (void) mem_size(mps, pages); // assert size return true; diff --git a/src/lefile.h b/src/lefile.h index 41f9b79d..ec1b41f4 100644 --- a/src/lefile.h +++ b/src/lefile.h @@ -26,8 +26,8 @@ */ #pragma once -#ifndef UPX_LEFILE_H__ -#define UPX_LEFILE_H__ 1 + +#include "util/membuffer.h" class InputFile; class OutputFile; @@ -38,7 +38,7 @@ class OutputFile; class LeFile { protected: - LeFile(InputFile *); + explicit LeFile(InputFile *) noexcept; virtual ~LeFile() noexcept; virtual bool readFileHeader(); @@ -187,8 +187,8 @@ protected: InputFile *fif = nullptr; OutputFile *fof = nullptr; - unsigned le_offset; - unsigned exe_offset; + unsigned le_offset = 0; + unsigned exe_offset = 0; le_header_t ih; le_header_t oh; @@ -212,23 +212,21 @@ protected: byte *ientries = nullptr; byte *oentries = nullptr; - unsigned soobject_table; - unsigned sofpage_table; - unsigned sopm_entries; - unsigned sores_names; - unsigned sofixups; - unsigned sononres_names; - unsigned soimage; - unsigned soentries; + unsigned soobject_table = 0; + unsigned sofpage_table = 0; + unsigned sopm_entries = 0; + unsigned sores_names = 0; + unsigned sofixups = 0; + unsigned sononres_names = 0; + unsigned soimage = 0; + unsigned soentries = 0; private: // disable copy and move - LeFile(const LeFile &) = delete; - LeFile &operator=(const LeFile &) = delete; - LeFile(LeFile &&) noexcept = delete; - LeFile &operator=(LeFile &&) noexcept = delete; + LeFile(const LeFile &) DELETED_FUNCTION; + LeFile &operator=(const LeFile &) DELETED_FUNCTION; + LeFile(LeFile &&) noexcept DELETED_FUNCTION; + LeFile &operator=(LeFile &&) noexcept DELETED_FUNCTION; }; -#endif /* already included */ - /* vim:set ts=4 sw=4 et: */ diff --git a/src/linker.h b/src/linker.h index 38ede2e4..01d3f531 100644 --- a/src/linker.h +++ b/src/linker.h @@ -75,7 +75,7 @@ protected: const char *symbol, upx_uint64_t add); public: - ElfLinker(const N_BELE_RTP::AbstractPolicy *b = &N_BELE_RTP::le_policy) noexcept; + explicit ElfLinker(const N_BELE_RTP::AbstractPolicy *b = &N_BELE_RTP::le_policy) noexcept; virtual ~ElfLinker() noexcept; void init(const void *pdata, int plen, unsigned pxtra = 0); @@ -123,7 +123,7 @@ struct ElfLinker::Section : private noncopyable { unsigned p2align = 0; // log2 Section *next = nullptr; - Section(const char *n, const void *i, unsigned s, unsigned a = 0); + explicit Section(const char *n, const void *i, unsigned s, unsigned a = 0); ~Section() noexcept; }; @@ -132,7 +132,7 @@ struct ElfLinker::Symbol : private noncopyable { Section *section = nullptr; upx_uint64_t offset = 0; - Symbol(const char *n, Section *s, upx_uint64_t o); + explicit Symbol(const char *n, Section *s, upx_uint64_t o); ~Symbol() noexcept; }; @@ -143,7 +143,8 @@ struct ElfLinker::Relocation : private noncopyable { const Symbol *value = nullptr; upx_uint64_t add; // used in .rela relocations - Relocation(const Section *s, unsigned o, const char *t, const Symbol *v, upx_uint64_t a); + explicit Relocation(const Section *s, unsigned o, const char *t, const Symbol *v, + upx_uint64_t a); ~Relocation() noexcept {} }; @@ -151,7 +152,7 @@ struct ElfLinker::Relocation : private noncopyable { // ElfLinker arch subclasses **************************************************************************/ -class ElfLinkerAMD64 : public ElfLinker { +class ElfLinkerAMD64 /*not_final*/ : public ElfLinker { typedef ElfLinker super; protected: virtual void alignCode(unsigned len) override { alignWithByte(len, 0x90); } @@ -169,7 +170,7 @@ protected: class ElfLinkerArmBE final : public ElfLinker { typedef ElfLinker super; public: - ElfLinkerArmBE() noexcept : super(&N_BELE_RTP::be_policy) {} + explicit ElfLinkerArmBE() noexcept : super(&N_BELE_RTP::be_policy) {} protected: virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value, const char *type) override; @@ -185,7 +186,7 @@ protected: class ElfLinkerM68k final : public ElfLinker { typedef ElfLinker super; public: - ElfLinkerM68k() noexcept : super(&N_BELE_RTP::be_policy) {} + explicit ElfLinkerM68k() noexcept : super(&N_BELE_RTP::be_policy) {} protected: virtual void alignCode(unsigned len) override; virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value, @@ -195,7 +196,7 @@ protected: class ElfLinkerMipsBE final : public ElfLinker { typedef ElfLinker super; public: - ElfLinkerMipsBE() noexcept : super(&N_BELE_RTP::be_policy) {} + explicit ElfLinkerMipsBE() noexcept : super(&N_BELE_RTP::be_policy) {} protected: virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value, const char *type) override; @@ -211,7 +212,7 @@ protected: class ElfLinkerPpc32 final : public ElfLinker { typedef ElfLinker super; public: - ElfLinkerPpc32() noexcept : super(&N_BELE_RTP::be_policy) {} + explicit ElfLinkerPpc32() noexcept : super(&N_BELE_RTP::be_policy) {} protected: virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value, const char *type) override; @@ -220,7 +221,7 @@ protected: class ElfLinkerPpc64 final : public ElfLinker { typedef ElfLinker super; public: - ElfLinkerPpc64() noexcept : super(&N_BELE_RTP::be_policy) {} + explicit ElfLinkerPpc64() noexcept : super(&N_BELE_RTP::be_policy) {} protected: virtual void relocate1(const Relocation *, byte *location, upx_uint64_t value, const char *type) override; diff --git a/src/p_com.h b/src/p_com.h index 042800e0..b43f7f60 100644 --- a/src/p_com.h +++ b/src/p_com.h @@ -35,7 +35,7 @@ class PackCom : public Packer { typedef Packer super; public: - PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; } + explicit PackCom(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; } virtual int getVersion() const override { return 13; } virtual int getFormat() const override { return UPX_F_DOS_COM; } virtual const char *getName() const override { return "dos/com"; } diff --git a/src/p_djgpp2.cpp b/src/p_djgpp2.cpp index b1490f10..a371fc48 100644 --- a/src/p_djgpp2.cpp +++ b/src/p_djgpp2.cpp @@ -371,7 +371,7 @@ void PackDjgpp2::unpack(OutputFile *fo) { // decompress decompress(ibuf, obuf); - coff_header_t *chdr = (coff_header_t *) raw_bytes(obuf, sizeof(coff_header_t)); + coff_header_t *const chdr = (coff_header_t *) raw_bytes(obuf, sizeof(coff_header_t)); text = &chdr->sh[0]; data = &chdr->sh[1]; bss = &chdr->sh[2]; diff --git a/src/p_djgpp2.h b/src/p_djgpp2.h index e1d29a51..7744abfe 100644 --- a/src/p_djgpp2.h +++ b/src/p_djgpp2.h @@ -37,7 +37,7 @@ class PackDjgpp2 final : public Packer { typedef Packer super; public: - PackDjgpp2(InputFile *f); + explicit PackDjgpp2(InputFile *f); virtual int getVersion() const override { return 14; } virtual int getFormat() const override { return UPX_F_DJGPP2_COFF; } virtual const char *getName() const override { return "djgpp2/coff"; } diff --git a/src/p_exe.h b/src/p_exe.h index 43c4e8bf..d4f2f5ac 100644 --- a/src/p_exe.h +++ b/src/p_exe.h @@ -35,7 +35,7 @@ class PackExe final : public Packer { typedef Packer super; public: - PackExe(InputFile *f); + explicit PackExe(InputFile *f); virtual int getVersion() const override { return 13; } virtual int getFormat() const override { return UPX_F_DOS_EXE; } virtual const char *getName() const override { return "dos/exe"; } @@ -61,9 +61,9 @@ public: protected: struct exe_header_t; - virtual int readFileHeader(void); + int readFileHeader(void); - virtual int fillExeHeader(struct exe_header_t *) const; + int fillExeHeader(struct exe_header_t *) const; virtual void buildLoader(const Filter *ft) override; virtual Linker *newLinker() const override; void addLoaderEpilogue(int flag); diff --git a/src/p_ps1.h b/src/p_ps1.h index ef3adedd..0724ac07 100644 --- a/src/p_ps1.h +++ b/src/p_ps1.h @@ -39,7 +39,7 @@ class PackPs1 final : public Packer { typedef Packer super; public: - PackPs1(InputFile *f); + explicit PackPs1(InputFile *f); virtual int getVersion() const override { return 13; } virtual int getFormat() const override { return UPX_F_PS1_EXE; } virtual const char *getName() const override { return "ps1/exe"; } diff --git a/src/p_sys.h b/src/p_sys.h index 2d9b354e..da34a9c9 100644 --- a/src/p_sys.h +++ b/src/p_sys.h @@ -35,7 +35,7 @@ class PackSys final : public PackCom { typedef PackCom super; public: - PackSys(InputFile *f) : super(f) {} + explicit PackSys(InputFile *f) : super(f) {} virtual int getVersion() const override { return 13; } virtual int getFormat() const override { return UPX_F_DOS_SYS; } virtual const char *getName() const override { return "dos/sys"; } diff --git a/src/p_tmt.cpp b/src/p_tmt.cpp index 75a27438..051b3c36 100644 --- a/src/p_tmt.cpp +++ b/src/p_tmt.cpp @@ -106,12 +106,12 @@ int PackTmt::readFileHeader() { adam_offset -= 512; if (H(0x18 / 2) == 0x40 && H4(0x3c)) adam_offset = H4(0x3c); - } else if (memcmp(h, "BW", 2) == 0) + } else if (memcmp(h, "BW", 2) == 0) { adam_offset += H(2) * 512 + H(1); - else if (memcmp(h, "PMW1", 4) == 0) { + } else if (memcmp(h, "PMW1", 4) == 0) { fi->seek(adam_offset + H4(0x18), SEEK_SET); adam_offset += H4(0x24); - int objs = H4(0x1c); + unsigned objs = H4(0x1c); while (objs--) { fi->readx(h, 0x18); adam_offset += H4(4); @@ -123,9 +123,9 @@ int PackTmt::readFileHeader() { fi->readx(h, 4); // + data_pages_offset adam_offset = offs + H4(0); - } else if (memcmp(h, "Adam", 4) == 0) + } else if (memcmp(h, "Adam", 4) == 0) { break; - else + } else return 0; } if (ic == 20) diff --git a/src/p_tmt.h b/src/p_tmt.h index 69bd45ec..97fd9a6c 100644 --- a/src/p_tmt.h +++ b/src/p_tmt.h @@ -35,7 +35,7 @@ class PackTmt final : public Packer { typedef Packer super; public: - PackTmt(InputFile *f); + explicit PackTmt(InputFile *f); virtual int getVersion() const override { return 13; } virtual int getFormat() const override { return UPX_F_TMT_ADAM; } virtual const char *getName() const override { return "tmt/adam"; } diff --git a/src/p_tos.h b/src/p_tos.h index bd2f1e72..d752d518 100644 --- a/src/p_tos.h +++ b/src/p_tos.h @@ -35,7 +35,7 @@ class PackTos final : public Packer { typedef Packer super; public: - PackTos(InputFile *f); + explicit PackTos(InputFile *f); virtual int getVersion() const override { return 13; } virtual int getFormat() const override { return UPX_F_ATARI_TOS; } virtual const char *getName() const override { return "atari/tos"; } diff --git a/src/p_w32pe_i386.h b/src/p_w32pe_i386.h index 7c48e35b..20923691 100644 --- a/src/p_w32pe_i386.h +++ b/src/p_w32pe_i386.h @@ -35,7 +35,7 @@ class PackW32PeI386 final : public PeFile32 { typedef PeFile32 super; public: - PackW32PeI386(InputFile *f); + explicit PackW32PeI386(InputFile *f); virtual ~PackW32PeI386() noexcept; virtual int getFormat() const override { return UPX_F_W32PE_I386; } virtual const char *getName() const override { return isrtm ? "rtm32/pe" : "win32/pe"; } diff --git a/src/p_w64pe_amd64.h b/src/p_w64pe_amd64.h index c2e35fc2..ac1e9296 100644 --- a/src/p_w64pe_amd64.h +++ b/src/p_w64pe_amd64.h @@ -35,7 +35,7 @@ class PackW64PeAmd64 final : public PeFile64 { typedef PeFile64 super; public: - PackW64PeAmd64(InputFile *f); + explicit PackW64PeAmd64(InputFile *f); virtual ~PackW64PeAmd64() noexcept; virtual int getFormat() const override { return UPX_F_W64PE_AMD64; } virtual const char *getName() const override { return "win64/pe"; } diff --git a/src/p_w64pe_arm64.h b/src/p_w64pe_arm64.h index 720ad393..d0c37d18 100644 --- a/src/p_w64pe_arm64.h +++ b/src/p_w64pe_arm64.h @@ -35,7 +35,7 @@ class PackW64PeArm64 : public PeFile64 { typedef PeFile64 super; public: - PackW64PeArm64(InputFile *f); + explicit PackW64PeArm64(InputFile *f); virtual ~PackW64PeArm64() noexcept {} virtual int getFormat() const override { return UPX_F_W64PE_ARM64; } virtual const char *getName() const override { return "win64/arm64"; } @@ -69,7 +69,7 @@ class PackW64PeArm64EC final : public PackW64PeArm64 { typedef PackW64PeArm64 super; public: - PackW64PeArm64EC(InputFile *f) : super(f) {} + explicit PackW64PeArm64EC(InputFile *f) : super(f) {} virtual int getFormat() const override { return UPX_F_W64PE_ARM64EC; } virtual const char *getName() const override { return "win64/arm64ec"; } virtual const char *getFullName(const Options *) const override { return "arm64ec-win64.pe"; } diff --git a/src/p_wcle.cpp b/src/p_wcle.cpp index b3688645..912c738e 100644 --- a/src/p_wcle.cpp +++ b/src/p_wcle.cpp @@ -690,7 +690,7 @@ void PackWcle::decodeObjectTable() { void PackWcle::decodeImage() { mb_oimage.allocForDecompression(ph.u_len); - oimage = mb_oimage; + oimage = mb_oimage; // => now a SPAN_S decompress(iimage + ph.buf_offset + ph.getPackHeaderSize(), oimage); soimage = get_le32(oimage + ph.u_len - 5); @@ -782,7 +782,7 @@ void PackWcle::unpack(OutputFile *fo) { ft.cto = (byte) ph.filter_cto; if (ph.version < 11) ft.cto = (byte) (get_le32(oimage + ph.u_len - 9) >> 24); - ft.unfilter(raw_bytes(oimage + text_vaddr, text_size), text_size); + ft.unfilter(oimage + text_vaddr, text_size); } decodeFixupPageTable(); diff --git a/src/p_wcle.h b/src/p_wcle.h index 3e918a59..f7cb4689 100644 --- a/src/p_wcle.h +++ b/src/p_wcle.h @@ -35,7 +35,7 @@ class PackWcle final : public Packer, public LeFile { typedef Packer super; public: - PackWcle(InputFile *f) : super(f), LeFile(f) { bele = &N_BELE_RTP::le_policy; } + explicit PackWcle(InputFile *f) : super(f), LeFile(f) { bele = &N_BELE_RTP::le_policy; } virtual int getVersion() const override { return 13; } virtual int getFormat() const override { return UPX_F_WATCOM_LE; } virtual const char *getName() const override { return "watcom/le"; } @@ -81,9 +81,9 @@ protected: // temporary copy of the object descriptors MemBuffer iobject_desc; - int big_relocs; - bool has_extra_code; - unsigned neweip; + int big_relocs = 0; + bool has_extra_code = false; + unsigned neweip = 0; }; /* vim:set ts=4 sw=4 et: */ diff --git a/src/p_wince_arm.h b/src/p_wince_arm.h index 36fa8850..39939cd4 100644 --- a/src/p_wince_arm.h +++ b/src/p_wince_arm.h @@ -35,7 +35,7 @@ class PackWinCeArm final : public PeFile32 { typedef PeFile32 super; public: - PackWinCeArm(InputFile *f); + explicit PackWinCeArm(InputFile *f); virtual ~PackWinCeArm() noexcept; virtual int getFormat() const override { return UPX_F_WINCE_ARM; } virtual const char *getName() const override { return "wince/arm"; } diff --git a/src/packer.cpp b/src/packer.cpp index aa33a763..daf70b8f 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -36,9 +36,7 @@ // **************************************************************************/ -Packer::Packer(InputFile *f) - : bele(nullptr), fi(f), file_size(0), ph_format(-1), ph_version(-1), ibufgood(0), uip(nullptr), - linker(nullptr), last_patch(nullptr), last_patch_len(0), last_patch_off(0) { +Packer::Packer(InputFile *f) : fi(f) { if (fi != nullptr) file_size = fi->st_size(); mem_size_assert(1, file_size_u); @@ -47,10 +45,12 @@ Packer::Packer(InputFile *f) } Packer::~Packer() noexcept { - delete uip; - uip = nullptr; - delete linker; - linker = nullptr; + // owner + owner_delete(uip); + owner_delete(linker); + // references + bele = nullptr; + fi = nullptr; } // for PackMaster @@ -870,7 +870,7 @@ static const char *getIdentstr(unsigned *size, int small) { } void Packer::initLoader(const void *pdata, int plen, int small, int pextra) { - delete linker; + owner_delete(linker); linker = newLinker(); assert(bele == linker->bele); linker->init(pdata, plen, pextra); diff --git a/src/packer.h b/src/packer.h index 0ccd8402..5c1d434c 100644 --- a/src/packer.h +++ b/src/packer.h @@ -44,7 +44,7 @@ class PackHeader final { friend class Packer; // these are strictly private to friend Packer - PackHeader() noexcept; + explicit PackHeader() noexcept; void putPackHeader(SPAN_S(byte) p); bool decodePackHeaderFromBuf(SPAN_S(const byte) b, int blen); @@ -106,7 +106,7 @@ class Packer { friend class UiPacker; protected: - Packer(InputFile *f); + explicit Packer(InputFile *f); public: virtual ~Packer() noexcept; @@ -328,9 +328,9 @@ protected: upx_uint64_t file_size_u; // explicitly unsigned }; - PackHeader ph = {}; // must be filled by canUnpack() - int ph_format = 0; - int ph_version = 0; + PackHeader ph = PackHeader{}; // must be filled by canUnpack() + int ph_format = -1; + int ph_version = -1; // compression buffers MemBuffer ibuf; // input @@ -338,10 +338,10 @@ protected: unsigned ibufgood = 0; // high-water mark in ibuf (pefile.cpp) // UI handler - UiPacker *uip = nullptr; + OwningPointer(UiPacker) uip = nullptr; // owner // linker - Linker *linker = nullptr; + OwningPointer(Linker) linker = nullptr; // owner private: // private to checkPatch() @@ -351,10 +351,10 @@ private: private: // disable copy and move - Packer(const Packer &) = delete; - Packer &operator=(const Packer &) = delete; - Packer(Packer &&) noexcept = delete; - Packer &operator=(Packer &&) noexcept = delete; + Packer(const Packer &) DELETED_FUNCTION; + Packer &operator=(const Packer &) DELETED_FUNCTION; + Packer(Packer &&) noexcept DELETED_FUNCTION; + Packer &operator=(Packer &&) noexcept DELETED_FUNCTION; }; int force_method(int method) noexcept; // (0x80ul<<24)|method diff --git a/src/packmast.cpp b/src/packmast.cpp index 3dcd0f1c..c96a7bbd 100644 --- a/src/packmast.cpp +++ b/src/packmast.cpp @@ -72,8 +72,7 @@ PackMaster::PackMaster(InputFile *f, Options *o) noexcept : fi(f) { } PackMaster::~PackMaster() noexcept { - delete packer; - packer = nullptr; + owner_delete(packer); // restore global options if (saved_opt != nullptr) { #if WITH_THREADS diff --git a/src/packmast.h b/src/packmast.h index 5419607a..379cccec 100644 --- a/src/packmast.h +++ b/src/packmast.h @@ -37,7 +37,7 @@ class OutputFile; class PackMaster final { public: - PackMaster(InputFile *f, Options *o = nullptr) noexcept; + explicit PackMaster(InputFile *f, Options *o = nullptr) noexcept; ~PackMaster() noexcept; void pack(OutputFile *fo); @@ -50,8 +50,8 @@ public: static Packer *visitAllPackers(visit_func_t, InputFile *f, const Options *, void *user); private: - Packer *packer = nullptr; // owner - InputFile *fi = nullptr; // reference + OwningPointer(Packer) packer = nullptr; // owner + InputFile *fi = nullptr; // reference static Packer *getPacker(InputFile *f); static Packer *getUnpacker(InputFile *f); diff --git a/src/pefile.cpp b/src/pefile.cpp index b26f6d78..59085d56 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -2530,16 +2530,16 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask, OutputFile::dump(opt->debug.dump_stub_loader, loader, codesize); if ((ic = fo->getBytesWritten() & (sizeof(LEXX) - 1)) != 0) fo->write(ibuf, sizeof(LEXX) - ic); - fo->write(raw_bytes(otls, aligned_sotls), aligned_sotls); + fo->write(otls, aligned_sotls); fo->write(oloadconf, soloadconf); if ((ic = fo->getBytesWritten() & fam1) != 0) fo->write(ibuf, oh.filealign - ic); if (!last_section_rsrc_only) - fo->write(raw_bytes(oresources, soresources), soresources); + fo->write(oresources, soresources); else fo->write(oxrelocs, soxrelocs); fo->write(oimpdlls, soimpdlls); - fo->write(raw_bytes(oexport, soexport), soexport); + fo->write(oexport, soexport); if (!last_section_rsrc_only) fo->write(oxrelocs, soxrelocs); @@ -2547,7 +2547,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, unsigned subsystem_mask, fo->write(ibuf, oh.filealign - ic); if (last_section_rsrc_only) { - fo->write(raw_bytes(oresources, soresources), soresources); + fo->write(oresources, soresources); if ((ic = fo->getBytesWritten() & fam1) != 0) fo->write(ibuf, oh.filealign - ic); } @@ -2658,7 +2658,7 @@ void PeFile::rebuildTls() { namespace { template -struct VPtr { // "virtual pointer" pointing before a buffer +struct VPtr final { // "virtual pointer" pointing before a buffer static_assert(sizeof(T) == 1); SPAN_S(T) base; size_t x; diff --git a/src/pefile.h b/src/pefile.h index 9d1005a6..5af8efb5 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -27,8 +27,6 @@ #pragma once -#include "util/membuffer.h" - /************************************************************************* // general/pe handling **************************************************************************/ @@ -45,7 +43,7 @@ protected: class ImportLinker; struct pe_section_t; - PeFile(InputFile *f); + explicit PeFile(InputFile *f); virtual ~PeFile() noexcept; void readSectionHeaders(unsigned objs, unsigned sizeof_ih); @@ -235,6 +233,7 @@ protected: PEDIR_EXCEPTION = 3, // Exception table PEDIR_SECURITY = 4, // Certificate table (file pointer) PEDIR_BASERELOC = 5, + PEDIR_RELOC = PEDIR_BASERELOC, PEDIR_DEBUG = 6, PEDIR_ARCHITECTURE = 7, // Architecture-specific data PEDIR_GLOBALPTR = 8, // Global pointer @@ -244,7 +243,6 @@ protected: PEDIR_IAT = 12, PEDIR_DELAY_IMPORT = 13, // Delay Import Descriptor PEDIR_COM_DESCRIPTOR = 14, // Com+ Runtime Header - PEDIR_RELOC = PEDIR_BASERELOC, }; // section flags @@ -370,7 +368,7 @@ protected: unsigned ivnum; - Interval(void *b); + explicit Interval(void *b); ~Interval() noexcept; void add(unsigned start, unsigned len); @@ -398,8 +396,8 @@ protected: unsigned counts[16]; public: - Reloc(byte *, unsigned); - Reloc(unsigned relocnum); + explicit Reloc(byte *, unsigned); + explicit Reloc(unsigned relocnum); // bool next(unsigned &pos, unsigned &type); const unsigned *getcounts() const { return counts; } @@ -438,8 +436,8 @@ protected: void ibufcheck(const void *m, unsigned size); public: - Resource(const byte *ibufstart, const byte *ibufen); - Resource(const byte *p, const byte *ibufstart, const byte *ibufend); + explicit Resource(const byte *ibufstart, const byte *ibufen); + explicit Resource(const byte *p, const byte *ibufstart, const byte *ibufend); ~Resource() noexcept; void init(const byte *); @@ -487,7 +485,7 @@ protected: Interval iv; public: - Export(char *_base); + explicit Export(char *_base); ~Export() noexcept; void convert(unsigned eoffs, unsigned esize); @@ -499,7 +497,7 @@ protected: class PeFile32 : public PeFile { typedef PeFile super; protected: - PeFile32(InputFile *f); + explicit PeFile32(InputFile *f); virtual ~PeFile32() noexcept; void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase, @@ -560,7 +558,7 @@ protected: class PeFile64 : public PeFile { typedef PeFile super; protected: - PeFile64(InputFile *f); + explicit PeFile64(InputFile *f); virtual ~PeFile64() noexcept; void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase); diff --git a/src/ui.cpp b/src/ui.cpp index bb66c43f..2823a15e 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -185,8 +185,8 @@ UiPacker::UiPacker(const Packer *p_) : p(p_) { UiPacker::~UiPacker() noexcept { cb.reset(); - delete s; - s = nullptr; + // owner + owner_delete(s); } /************************************************************************* diff --git a/src/ui.h b/src/ui.h index 12ebbc83..8bf94f0a 100644 --- a/src/ui.h +++ b/src/ui.h @@ -36,7 +36,7 @@ class Packer; class UiPacker final { public: - UiPacker(const Packer *p_); + explicit UiPacker(const Packer *p_); public: virtual ~UiPacker() noexcept; @@ -84,14 +84,14 @@ public: protected: virtual void printInfo(int nl = 0); - const Packer *const p; + const Packer *const p; // reference // callback upx_callback_t cb = {}; // internal state struct State; - State *s = nullptr; + OwningPointer(State) s = nullptr; // owner // totals static unsigned total_files; diff --git a/src/util/membuffer.h b/src/util/membuffer.h index 5fefbc0e..a9c1769c 100644 --- a/src/util/membuffer.h +++ b/src/util/membuffer.h @@ -48,7 +48,7 @@ protected: size_type size_in_bytes; public: - inline MemBufferBase() noexcept : ptr(nullptr), size_in_bytes(0) {} + explicit inline MemBufferBase() noexcept : ptr(nullptr), size_in_bytes(0) {} forceinline ~MemBufferBase() noexcept {} // IMPORTANT NOTE: automatic conversion to underlying pointer @@ -148,7 +148,7 @@ inline typename MemBufferBase::pointer raw_index_bytes(const MemBufferBase class MemBuffer final : public MemBufferBase { public: - inline MemBuffer() noexcept : MemBufferBase() {} + explicit inline MemBuffer() noexcept : MemBufferBase() {} explicit MemBuffer(upx_uint64_t bytes); ~MemBuffer() noexcept; diff --git a/src/util/util.cpp b/src/util/util.cpp index afaf2948..40e02485 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -151,7 +151,7 @@ void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, s if very_unlikely (a_end < a || b_end < b) // wrap-around throwCantPack("ptr_check_no_overlap-overflow"); // same as (!(a >= b_end || b >= a_end)) - if (a < b_end && b < a_end) + if very_unlikely (a < b_end && b < a_end) throwCantPack("ptr_check_no_overlap-ab"); } @@ -165,11 +165,11 @@ void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, s upx_uintptr_t c_end = c + mem_size(1, c_size); if very_unlikely (a_end < a || b_end < b || c_end < c) // wrap-around throwCantPack("ptr_check_no_overlap-overflow"); - if (a < b_end && b < a_end) + if very_unlikely (a < b_end && b < a_end) throwCantPack("ptr_check_no_overlap-ab"); - if (a < c_end && c < a_end) + if very_unlikely (a < c_end && c < a_end) throwCantPack("ptr_check_no_overlap-ac"); - if (b < c_end && c < b_end) + if very_unlikely (b < c_end && c < b_end) throwCantPack("ptr_check_no_overlap-bc"); } diff --git a/src/util/xspan.h b/src/util/xspan.h index fa891d25..f32cf82e 100644 --- a/src/util/xspan.h +++ b/src/util/xspan.h @@ -120,7 +120,7 @@ using XSPAN_NAMESPACE_NAME::raw_index_bytes; // overloaded for all classes // helper for implicit pointer conversions and MemBuffer overloads template -inline R *xspan_make_helper__(R * /*dummy*/, T *first) /*may_throw*/ { +inline R *xspan_make_helper__(R * /*dummy*/, T *first) may_throw { return first; // IMPORTANT: no cast here to detect bad usage } template diff --git a/src/util/xspan_impl_common.h b/src/util/xspan_impl_common.h index 9fac0961..2fcae2e9 100644 --- a/src/util/xspan_impl_common.h +++ b/src/util/xspan_impl_common.h @@ -394,31 +394,31 @@ public: private: pointer check_deref(pointer p) const { + assertInvariants(); if __acc_cte (!configRequirePtr && p == nullptr) xspan_fail_nullptr(); if __acc_cte (configRequireBase || base != nullptr) xspan_check_range(p, base, size_in_bytes - sizeof(T)); - assertInvariants(); return p; } pointer check_deref(pointer p, ptrdiff_t n) const { + assertInvariants(); if __acc_cte (!configRequirePtr && p == nullptr) xspan_fail_nullptr(); xspan_mem_size_assert_ptrdiff(n); p += n; if __acc_cte (configRequireBase || base != nullptr) xspan_check_range(p, base, size_in_bytes - sizeof(T)); - assertInvariants(); return p; } pointer check_add(pointer p, ptrdiff_t n) const { + assertInvariants(); if __acc_cte (!configRequirePtr && p == nullptr) xspan_fail_nullptr(); xspan_mem_size_assert_ptrdiff(n); p += n; if __acc_cte (configRequireBase || base != nullptr) xspan_check_range(p, base, size_in_bytes); - assertInvariants(); return p; }