diff --git a/src/Makefile b/src/Makefile index 676d45b9..577c0842 100644 --- a/src/Makefile +++ b/src/Makefile @@ -61,7 +61,6 @@ LIBS += -lucl -lz # LZMA from https://github.com/upx/upx-lzma-sdk include $(top_srcdir)/src/stub/src/c/Makevars.lzma DEFS += -DWITH_LZMA=$(UPX_LZMA_VERSION) -INCLUDES += -I$(UPX_LZMADIR) CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) ifdef USE_DEBUG @@ -75,7 +74,7 @@ ifeq ($(findstring clang,$(CXX)),) CXXFLAGS += -fno-delete-null-pointer-checks endif CXXFLAGS += -fno-strict-aliasing -fwrapv -CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wshadow -Wwrite-strings +CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wmissing-declarations -Wpointer-arith -Wshadow -Wwrite-strings CXXFLAGS_WERROR ?= -Werror CXXFLAGS += $(CXXFLAGS_WERROR) @@ -109,6 +108,8 @@ else endif +.depend compress_lzma$(objext) : INCLUDES += -I$(UPX_LZMADIR) + compress_lzma$(objext) : CXXFLAGS += -Wno-shadow p_mach$(objext) : CXXFLAGS += -Wno-cast-align @@ -122,6 +123,14 @@ ifeq ($(MAKECMDGOALS),mostlyclean) else ifeq ($(MAKECMDGOALS),clean) else ifeq ($(MAKECMDGOALS),distclean) else ifeq ($(MAKECMDGOALS),maintainer-clean) +else ifeq ($(MAKECMDGOALS),clang-format) else -include .depend endif + + +CLANG_FORMAT_FILES += snprintf.cpp +CLANG_FORMAT_FILES += stdcxx.h stdcxx.cpp +clang-format: + $(top_srcdir)/src/stub/scripts/upx-clang-format -i $(addprefix $(top_srcdir)/src/,$(CLANG_FORMAT_FILES)) +.PHONY: clang-format diff --git a/src/compress.cpp b/src/compress.cpp index dea0a1ee..5614d199 100644 --- a/src/compress.cpp +++ b/src/compress.cpp @@ -29,7 +29,6 @@ #include "conf.h" #include "compress.h" #include "mem.h" -#include /************************************************************************* @@ -41,12 +40,10 @@ unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) if (len == 0) return adler; assert(buf != NULL); -#if 0 - return adler32(adler, (const Bytef *) buf, len); // zlib -#elif (WITH_UCL) - return ucl_adler32(adler, (const ucl_bytep) buf, len); +#if 1 + return upx_ucl_adler32(buf, len, adler); #else -# error + return upx_zlib_adler32(buf, len, adler); #endif } @@ -57,12 +54,10 @@ unsigned upx_crc32(const void *buf, unsigned len, unsigned crc) if (len == 0) return crc; assert(buf != NULL); -#if 0 - return crc32(crc, (const Bytef *) buf, len); // zlib -#elif (WITH_UCL) - return ucl_crc32(crc, (const ucl_bytep) buf, len); +#if 1 + return upx_ucl_crc32(buf, len, crc); #else -# error + return upx_zlib_crc32(buf, len, crc); #endif } #endif /* UNUSED */ diff --git a/src/compress.h b/src/compress.h index ff264b20..4245b81a 100644 --- a/src/compress.h +++ b/src/compress.h @@ -35,6 +35,7 @@ **************************************************************************/ #if (WITH_LZMA) +int upx_lzma_init(void); const char *upx_lzma_version_string(void); int upx_lzma_compress ( const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned* dst_len, @@ -56,6 +57,7 @@ int upx_lzma_test_overlap ( const upx_bytep buf, #if (WITH_NRV) +int upx_nrv_init(void); const char *upx_nrv_version_string(void); int upx_nrv_compress ( const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned* dst_len, @@ -77,6 +79,7 @@ int upx_nrv_test_overlap ( const upx_bytep buf, #if (WITH_UCL) +int upx_ucl_init(void); const char *upx_ucl_version_string(void); int upx_ucl_compress ( const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned* dst_len, @@ -94,10 +97,13 @@ int upx_ucl_test_overlap ( const upx_bytep buf, unsigned* dst_len, int method, const upx_compress_result_t *cresult ); +unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler); +unsigned upx_ucl_crc32 (const void *buf, unsigned len, unsigned crc); #endif #if (WITH_ZLIB) +int upx_zlib_init(void); const char *upx_zlib_version_string(void); int upx_zlib_compress ( const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned* dst_len, @@ -115,6 +121,8 @@ int upx_zlib_test_overlap ( const upx_bytep buf, unsigned* dst_len, int method, const upx_compress_result_t *cresult ); +unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler); +unsigned upx_zlib_crc32 (const void *buf, unsigned len, unsigned crc); #endif diff --git a/src/compress_lzma.cpp b/src/compress_lzma.cpp index 2f275e4e..ccf8a04b 100644 --- a/src/compress_lzma.cpp +++ b/src/compress_lzma.cpp @@ -787,13 +787,21 @@ int upx_lzma_test_overlap ( const upx_bytep buf, // misc **************************************************************************/ +int upx_lzma_init(void) +{ + return 0; +} + const char *upx_lzma_version_string(void) { #if (WITH_LZMA >= 0x461) +# error "invalid WITH_LZMA version" return MY_VERSION; #elif (WITH_LZMA + 0 == 0x457) +# error "invalid WITH_LZMA version" return "4.57"; #elif (WITH_LZMA + 0 == 0x449) +# error "invalid WITH_LZMA version" return "4.49"; #elif (WITH_LZMA + 0 == 0x443) return "4.43"; diff --git a/src/compress_ucl.cpp b/src/compress_ucl.cpp index d260a244..06675a19 100644 --- a/src/compress_ucl.cpp +++ b/src/compress_ucl.cpp @@ -281,11 +281,29 @@ int upx_ucl_test_overlap ( const upx_bytep buf, // misc **************************************************************************/ +int upx_ucl_init(void) +{ + if (ucl_init() != UCL_E_OK) + return -1; + return 0; +} + const char *upx_ucl_version_string(void) { return ucl_version_string(); } +unsigned upx_ucl_adler32(const void *buf, unsigned len, unsigned adler) +{ + return ucl_adler32(adler, (const ucl_bytep) buf, len); +} + +#if 0 /* UNUSED */ +unsigned upx_ucl_crc32(const void *buf, unsigned len, unsigned crc) +{ + return ucl_crc32(crc, (const ucl_bytep) buf, len); +} +#endif #endif /* WITH_UCL */ /* diff --git a/src/compress_zlib.cpp b/src/compress_zlib.cpp index 891bd57d..164eedc9 100644 --- a/src/compress_zlib.cpp +++ b/src/compress_zlib.cpp @@ -222,11 +222,32 @@ int upx_zlib_test_overlap ( const upx_bytep buf, // misc **************************************************************************/ +int upx_zlib_init(void) +{ +#if defined(UPX_OFFICIAL_BUILD) + if (strcmp(ZLIB_VERSION, zlibVersion()) != 0) + return -2; +#endif + return 0; +} + const char *upx_zlib_version_string(void) { return zlibVersion(); } +unsigned upx_zlib_adler32(const void *buf, unsigned len, unsigned adler) +{ + return adler32(adler, (const Bytef *) buf, len); +} + +#if 0 /* UNUSED */ +unsigned upx_zlib_crc32(const void *buf, unsigned len, unsigned crc) +{ + return crc32(crc, (const Bytef *) buf, len); +} +#endif + #endif /* WITH_ZLIB */ /* diff --git a/src/conf.h b/src/conf.h index e572272c..f3be97fb 100644 --- a/src/conf.h +++ b/src/conf.h @@ -112,23 +112,18 @@ typedef acc_uintptr_t upx_uintptr_t; # undef __unix #endif -#if !defined(WITH_UCL) -# define WITH_UCL 1 -#endif +#define WITH_UCL 1 +#define WITH_ZLIB 1 #if !defined(WITH_LZMA) || (WITH_LZMA+0 == 0) # error "WITH_LZMA is missing" -#endif -#if (WITH_LZMA != 0x443) +#elif (WITH_LZMA != 0x443) # error "invalid WITH_LZMA version" #endif #if defined(UPX_OFFICIAL_BUILD) -# if !(WITH_LZMA) || !(WITH_NRV) || !(WITH_UCL) +# if !(WITH_LZMA && WITH_NRV && WITH_UCL && WITH_ZLIB) # error # endif #endif -#if (WITH_NRV) -# include -#endif #if (WITH_UCL) # define ucl_compress_config_t REAL_ucl_compress_config_t # include @@ -160,7 +155,7 @@ typedef acc_uintptr_t upx_uintptr_t; #endif -// unconditionally turn on assertions +// IMPORTANT: unconditionally enable assertions #undef NDEBUG #include @@ -473,9 +468,11 @@ struct OptVar static const T min_value_c = min_value; static const T max_value_c = max_value; - void assertValue() { - // FIXME: this generates annoying warnings "unsigned >= 0 is always true" - //assert((v >= min_value) && (v <= max_value)); + void assertValue() const { + // info: this generates annoying warnings "unsigned >= 0 is always true" + //assert(v >= min_value_c); + assert(v == min_value_c || v >= min_value_c + 1); + assert(v <= max_value_c); } OptVar() : v(default_value), is_set(0) { } @@ -494,10 +491,12 @@ struct OptVar // optional assignments -template inline void oassign(T &self, const T &other) { +template +inline void oassign(OptVar &self, const OptVar &other) { if (other.is_set) { self.v = other.v; self.is_set += 1; } } -template inline void oassign(unsigned &v, const T &other) { +template +inline void oassign(unsigned &v, const OptVar &other) { if (other.is_set) { v = other.v; } } diff --git a/src/main.cpp b/src/main.cpp index 72a55918..7263860f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,6 +27,7 @@ #include "conf.h" +#include "compress.h" #include "file.h" #include "packer.h" #include "p_elf.h" @@ -171,20 +172,22 @@ void e_exit(int ec) } -void e_usage(void) +static void e_usage(void) { show_usage(); e_exit(EXIT_USAGE); } -void e_memory(void) +#if 0 // UNUSED +static void e_memory(void) { show_head(); fflush(con_term); fprintf(stderr,"%s: out of memory\n", argv0); e_exit(EXIT_MEMORY); } +#endif // UNUSED static void e_method(int m, int l) @@ -212,7 +215,7 @@ static void e_optval(const char *n) #if defined(OPTIONS_VAR) -void e_envopt(const char *n) +static void e_envopt(const char *n) { fflush(con_term); if (n) @@ -226,18 +229,20 @@ void e_envopt(const char *n) #endif /* defined(OPTIONS_VAR) */ -void __acc_cdecl_sighandler e_sighandler(int signum) +#if 0 // UNUSED +static void __acc_cdecl_sighandler e_sighandler(int signum) { UNUSED(signum); e_exit(EXIT_FATAL); } +#endif // UNUSED /************************************************************************* // check options **************************************************************************/ -void check_not_both(bool e1, bool e2, const char *c1, const char *c2) +static void check_not_both(bool e1, bool e2, const char *c1, const char *c2) { if (e1 && e2) { @@ -248,7 +253,7 @@ void check_not_both(bool e1, bool e2, const char *c1, const char *c2) } -void check_options(int i, int argc) +static void check_options(int i, int argc) { assert(i <= argc); @@ -298,7 +303,7 @@ void check_options(int i, int argc) // misc **************************************************************************/ -void e_help(void) +static void e_help(void) { show_help(); e_exit(EXIT_USAGE); @@ -439,7 +444,7 @@ char* prepare_shortopts(char *buf, const char *n, template -int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal) +static int getoptvar(T *var, const T min_value, const T max_value, const char *arg_fatal) { const char *p = mfx_optarg; char *endptr; @@ -470,7 +475,7 @@ done: } template -int getoptvar(OptVar *var, const char *arg_fatal) +static int getoptvar(OptVar *var, const char *arg_fatal) { T v = default_value; int r = getoptvar(&v, min_value, max_value, arg_fatal); @@ -1310,7 +1315,7 @@ static bool test(void) #undef ACCCHK_ASSERT #include "miniacc.h" -void upx_sanity_check(void) +__acc_static_noinline void upx_sanity_check(void) { #define ACC_WANT_ACC_CHK_CH 1 #undef ACCCHK_ASSERT @@ -1347,7 +1352,7 @@ void upx_sanity_check(void) COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_YEAR) == 4 + 1) assert(strlen(UPX_VERSION_YEAR) == 4); assert(memcmp(UPX_VERSION_DATE_ISO, UPX_VERSION_YEAR, 4) == 0); - assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0); + assert(memcmp(&UPX_VERSION_DATE[strlen(UPX_VERSION_DATE) - 4], UPX_VERSION_YEAR, 4) == 0); #if 1 assert(TestBELE::test()); @@ -1464,8 +1469,7 @@ int __acc_cdecl_main main(int argc, char *argv[]) set_term(stderr); -#if (WITH_UCL) - if (ucl_init() != UCL_E_OK) + if (upx_ucl_init() != 0) { show_head(); fprintf(stderr,"ucl_init() failed - check your UCL installation !\n"); @@ -1474,17 +1478,10 @@ int __acc_cdecl_main main(int argc, char *argv[]) (long) UCL_VERSION, (long) ucl_version()); e_exit(EXIT_INIT); } -#endif + assert(upx_lzma_init() == 0); + assert(upx_zlib_init() == 0); #if (WITH_NRV) - if (nrv_init() != NRV_E_OK || NRV_VERSION != nrv_version()) - { - show_head(); - fprintf(stderr,"nrv_init() failed - check your NRV installation !\n"); - if (NRV_VERSION != nrv_version()) - fprintf(stderr,"library version conflict (%lx, %lx) - check your NRV installation !\n", - (long) NRV_VERSION, (long) nrv_version()); - e_exit(EXIT_INIT); - } + assert(upx_nrv_init() == 0); #endif //srand((int) time(NULL)); diff --git a/src/mem.cpp b/src/mem.cpp index fc3c3345..2322968c 100644 --- a/src/mem.cpp +++ b/src/mem.cpp @@ -31,21 +31,22 @@ /************************************************************************* -// +// assert sane memory buffer sizes to protect against integer overflows +// and malicious header fields **************************************************************************/ // DO NOT CHANGE -#define MAX_SIZE (768 * 1024 * 1024) -ACC_COMPILE_TIME_ASSERT_HEADER(2ull * MAX_SIZE * 9 / 8 + 16*1024*1024 < INT_MAX) +#define MAX_BUF_SIZE (768 * 1024 * 1024) +ACC_COMPILE_TIME_ASSERT_HEADER(2ull * MAX_BUF_SIZE * 9 / 8 + 16*1024*1024 < INT_MAX) size_t mem_size(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra) { assert(element_size > 0); - if (element_size > MAX_SIZE) throwCantPack("mem_size 1; take care"); - if (n > MAX_SIZE) throwCantPack("mem_size 2; take care"); - if (extra > MAX_SIZE) throwCantPack("mem_size 3; take care"); + if (element_size > MAX_BUF_SIZE) throwCantPack("mem_size 1; take care"); + if (n > MAX_BUF_SIZE) throwCantPack("mem_size 2; take care"); + if (extra > MAX_BUF_SIZE) throwCantPack("mem_size 3; take care"); upx_uint64_t bytes = element_size * n + extra; // cannot overflow - if (bytes > MAX_SIZE) throwCantPack("mem_size 4; take care"); + if (bytes > MAX_BUF_SIZE) throwCantPack("mem_size 4; take care"); return ACC_ICONV(size_t, bytes); } @@ -58,14 +59,16 @@ size_t mem_size_get_n(upx_uint64_t element_size, upx_uint64_t n) bool mem_size_valid(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra) { assert(element_size > 0); - if (element_size > MAX_SIZE) return false; - if (n > MAX_SIZE) return false; - if (extra > MAX_SIZE) return false; + if (element_size > MAX_BUF_SIZE) return false; + if (n > MAX_BUF_SIZE) return false; + if (extra > MAX_BUF_SIZE) return false; upx_uint64_t bytes = element_size * n + extra; // cannot overflow - if (bytes > MAX_SIZE) return false; + if (bytes > MAX_BUF_SIZE) return false; return true; } +#undef MAX_BUF_SIZE + /************************************************************************* // diff --git a/src/packer.cpp b/src/packer.cpp index 09ba208d..f6d62874 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -393,6 +393,7 @@ void Packer::decompress(const upx_bytep in, upx_bytep out, // overlapping decompression **************************************************************************/ +static bool ph_testOverlappingDecompression(const PackHeader &ph, const upx_bytep buf, const upx_bytep tbuf, diff --git a/src/pefile.cpp b/src/pefile.cpp index 493d80f6..e46b3a9c 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -39,25 +39,6 @@ // **************************************************************************/ -#if defined(__BORLANDC__) -# undef strcpy -# define strcpy(a,b) strcpy((char *)(a),(const char *)(b)) -#endif - -#if 1 -//static -unsigned my_strlen(const char *s) -{ - size_t l = strlen((const char*)s); assert((unsigned) l == l); return (unsigned) l; -} -static unsigned my_strlen(const unsigned char *s) -{ - size_t l = strlen((const char*)s); assert((unsigned) l == l); return (unsigned) l; -} -#undef strlen -#define strlen my_strlen -#endif - #include "bptr.h" #define IPTR(type, var) BoundedPtr var(ibuf, ibuf.getSize()) #define OPTR(type, var) BoundedPtr var(obuf, obuf.getSize()) diff --git a/src/snprintf.cpp b/src/snprintf.cpp index f52438e6..7d5ed944 100644 --- a/src/snprintf.cpp +++ b/src/snprintf.cpp @@ -131,13 +131,13 @@ // **************************************************************************/ -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, int c) { - if (*currlen < maxlen) - buffer[*currlen] = (char) c; - *currlen += 1; +__acc_static_forceinline void dopr_outch(char *buffer, size_t *currsize, size_t maxsize, int c) { + if (*currsize < maxsize) + buffer[*currsize] = (char) c; + *currsize += 1; } -static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, const char *value, int flags, +static void fmtstr(char *buffer, size_t *currsize, size_t maxsize, const char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; @@ -147,33 +147,32 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, const char *val #endif if (value == NULL) value = ""; - - for (strln = 0; value[strln];) /* strlen */ - ++strln; + strln = (int) strlen(value); padlen = min - strln; if (padlen < 0) padlen = 0; if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ - while ((padlen > 0) && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, ' '); + while (padlen > 0 && cnt < max) { + dopr_outch(buffer, currsize, maxsize, ' '); --padlen; ++cnt; } - while (*value && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, *value++); + while (*value && cnt < max) { + dopr_outch(buffer, currsize, maxsize, *value); + ++value; ++cnt; } - while ((padlen < 0) && (cnt < max)) { - dopr_outch(buffer, currlen, maxlen, ' '); + while (padlen < 0 && cnt < max) { + dopr_outch(buffer, currsize, maxsize, ' '); ++padlen; ++cnt; } } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, LLONG value, unsigned base, +static void fmtint(char *buffer, size_t *currsize, size_t maxsize, LLONG value, unsigned base, int min, int max, int flags) { int signvalue = 0; ULLONG uvalue; @@ -227,27 +226,27 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen, LLONG value, un /* Spaces */ while (spadlen > 0) { - dopr_outch(buffer, currlen, maxlen, ' '); + dopr_outch(buffer, currsize, maxsize, ' '); --spadlen; } /* Sign */ if (signvalue) - dopr_outch(buffer, currlen, maxlen, signvalue); + dopr_outch(buffer, currsize, maxsize, signvalue); /* Zeros */ while (zpadlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); + dopr_outch(buffer, currsize, maxsize, '0'); --zpadlen; } /* Digits */ while (place > 0) - dopr_outch(buffer, currlen, maxlen, convert[--place]); + dopr_outch(buffer, currsize, maxsize, convert[--place]); /* Left Justified spaces */ while (spadlen < 0) { - dopr_outch(buffer, currlen, maxlen, ' '); + dopr_outch(buffer, currsize, maxsize, ' '); ++spadlen; } } @@ -323,11 +322,11 @@ static double my_modf(double x0, double *iptr) { return x - *iptr; } -static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, int min, int max, +static void fmtfp(char *buffer, size_t *currsize, size_t maxsize, LDOUBLE fvalue, int min, int max, int flags) { /* avoid warnings with 'gcc -Wshadow' */ #undef index -#define index iindex +#define index fmtfp_index int signvalue = 0; double ufvalue; char iconvert[311 + 1]; @@ -432,24 +431,24 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { - dopr_outch(buffer, currlen, maxlen, signvalue); + dopr_outch(buffer, currsize, maxsize, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); + dopr_outch(buffer, currsize, maxsize, '0'); --padlen; } } while (padlen > 0) { - dopr_outch(buffer, currlen, maxlen, ' '); + dopr_outch(buffer, currsize, maxsize, ' '); --padlen; } if (signvalue) - dopr_outch(buffer, currlen, maxlen, signvalue); + dopr_outch(buffer, currsize, maxsize, signvalue); while (iplace > 0) - dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); + dopr_outch(buffer, currsize, maxsize, iconvert[--iplace]); #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); @@ -460,19 +459,16 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, * char to print out. */ if (max > 0) { - dopr_outch(buffer, currlen, maxlen, '.'); - + dopr_outch(buffer, currsize, maxsize, '.'); while (fplace > 0) - dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); + dopr_outch(buffer, currsize, maxsize, fconvert[--fplace]); } - while (zpadlen > 0) { - dopr_outch(buffer, currlen, maxlen, '0'); + dopr_outch(buffer, currsize, maxsize, '0'); --zpadlen; } - while (padlen < 0) { - dopr_outch(buffer, currlen, maxlen, ' '); + dopr_outch(buffer, currsize, maxsize, ' '); ++padlen; } #undef index @@ -484,7 +480,7 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue, // dopr() **************************************************************************/ -static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args) { +static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list args) { char ch; LLONG value; #if !(NO_FLOAT) @@ -496,10 +492,10 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args int state; int flags; int cflags; - size_t currlen; + size_t currsize; state = DP_S_DEFAULT; - currlen = flags = cflags = min = 0; + currsize = flags = cflags = min = 0; max = -1; ch = *format++; @@ -512,7 +508,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args if (ch == '%') state = DP_S_FLAGS; else - dopr_outch(buffer, &currlen, maxlen, ch); + dopr_outch(buffer, &currsize, maxsize, ch); ch = *format++; break; case DP_S_FLAGS: @@ -611,7 +607,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = va_arg(args, LLONG); else value = va_arg(args, int); - fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); + fmtint(buffer, &currsize, maxsize, value, 10, min, max, flags); break; case 'o': flags |= DP_F_UNSIGNED; @@ -623,7 +619,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (long) va_arg(args, ULLONG); else value = (long) va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); + fmtint(buffer, &currsize, maxsize, value, 8, min, max, flags); break; case 'u': flags |= DP_F_UNSIGNED; @@ -635,7 +631,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (LLONG) va_arg(args, ULLONG); else value = (long) va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); + fmtint(buffer, &currsize, maxsize, value, 10, min, max, flags); break; case 'X': flags |= DP_F_UP; @@ -649,7 +645,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (LLONG) va_arg(args, ULLONG); else value = (long) va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); + fmtint(buffer, &currsize, maxsize, value, 16, min, max, flags); break; #if !(NO_FLOAT) case 'f': @@ -658,7 +654,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args else fvalue = va_arg(args, double); /* um, floating point? */ - fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); + fmtfp(buffer, &currsize, maxsize, fvalue, min, max, flags); break; case 'E': flags |= DP_F_UP; @@ -686,45 +682,44 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args exit(255); #endif /* !(NO_FLOAT) */ case 'c': - dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); + dopr_outch(buffer, &currsize, maxsize, va_arg(args, int)); break; case 's': strvalue = va_arg(args, const char *); if (!strvalue) strvalue = "(NULL)"; - if (max == -1) { + if (max == -1) max = (int) strlen(strvalue); - } if (min > 0 && max >= 0 && min > max) max = min; - fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); + fmtstr(buffer, &currsize, maxsize, strvalue, flags, min, max); break; case 'p': strvalue = (const char *) va_arg(args, const void *); - fmtint(buffer, &currlen, maxlen, (LLONG)(upx_uintptr_t) strvalue, 16, min, max, + fmtint(buffer, &currsize, maxsize, (LLONG)(upx_uintptr_t) strvalue, 16, min, max, flags); break; case 'n': if (cflags == DP_C_SHORT) { short int *num; num = va_arg(args, short int *); - *num = (short int) currlen; + *num = (short int) currsize; } else if (cflags == DP_C_LONG) { long int *num; num = va_arg(args, long int *); - *num = (long int) currlen; + *num = (long int) currsize; } else if (cflags == DP_C_LLONG) { LLONG *num; num = va_arg(args, LLONG *); - *num = (LLONG) currlen; + *num = (LLONG) currsize; } else { int *num; num = va_arg(args, int *); - *num = (int) currlen; + *num = (int) currsize; } break; case '%': - dopr_outch(buffer, &currlen, maxlen, ch); + dopr_outch(buffer, &currsize, maxsize, ch); break; case 'w': /* not supported yet, treat as next char */ @@ -746,83 +741,86 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args break; /* some picky compilers need this */ } } - if (maxlen != 0) { - if (currlen < maxlen - 1) - buffer[currlen] = '\0'; - else - buffer[maxlen - 1] = '\0'; - } - - return currlen; + dopr_outch(buffer, &currsize, maxsize, '\0'); + return currsize; // returns size, not length } /************************************************************************* // public entries **************************************************************************/ +// protect against integer overflows and malicious header fields +#define MAX_STR_SIZE (1024 * 1024) + // UPX version with assertions -__acc_static_noinline int xdopr(char *buffer, size_t maxlen, const char *format, va_list args) { - size_t ret; +int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap) { + size_t size; // preconditions - assert(maxlen < INT_MAX); - if (buffer != NULL) - assert(maxlen > 0); + assert(count <= MAX_STR_SIZE); + if (str != NULL) + assert(count > 0); else - assert(maxlen == 0); + assert(count == 0); - ret = dopr(buffer, maxlen, format, args); + size = dopr(str, count, format, ap); // postconditions - if (buffer != NULL) { - assert((int) ret >= 0); - assert(ret < maxlen); - assert(buffer[ret] == '\0'); + assert(size > 0); + assert(size <= MAX_STR_SIZE); + if (str != NULL) { + assert(size <= count); + assert(str[size - 1] == '\0'); } - return (int) ret; -} - -int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap) { - return xdopr(str, count, format, ap); + return ACC_ICONV(int, size - 1); // snprintf() returns length, not size } int __acc_cdecl_va upx_snprintf(char *str, size_t count, const char *format, ...) { va_list ap; - int ret; + int len; va_start(ap, format); - ret = xdopr(str, count, format, ap); + len = upx_vsnprintf(str, count, format, ap); va_end(ap); - return ret; + return len; } int upx_vasprintf(char **ptr, const char *format, va_list ap) { - int ret; + int len; assert(ptr != NULL); *ptr = NULL; - ret = xdopr(NULL, 0, format, ap); - if (ret > 0) { - *ptr = (char *) malloc(ret + 1); + len = upx_vsnprintf(NULL, 0, format, ap); + if (len >= 0) { + *ptr = (char *) malloc(len + 1); assert(*ptr != NULL); if (*ptr == NULL) return -1; - ret = xdopr(*ptr, ret + 1, format, ap); + len = upx_vsnprintf(*ptr, len + 1, format, ap); } - return ret; + return len; } int __acc_cdecl_va upx_asprintf(char **ptr, const char *format, ...) { va_list ap; - int ret; + int len; va_start(ap, format); - ret = upx_vasprintf(ptr, format, ap); + len = upx_vasprintf(ptr, format, ap); va_end(ap); - return ret; + return len; } +#undef strlen +size_t upx_strlen(const char *s) { + size_t len = strlen(s); + assert(len < MAX_STR_SIZE); + return len; +} + +#undef MAX_STR_SIZE + /************************************************************************* // **************************************************************************/ diff --git a/src/snprintf.h b/src/snprintf.h index 677afa31..ca5b2fd1 100644 --- a/src/snprintf.h +++ b/src/snprintf.h @@ -25,7 +25,6 @@ */ - #ifndef __UPX_SNPRINTF_H #define __UPX_SNPRINTF_H 1 @@ -33,21 +32,22 @@ extern "C" { #endif - /************************************************************************* // **************************************************************************/ int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap); -int __acc_cdecl_va upx_snprintf(char *str, size_t count, const char *format,...); +int __acc_cdecl_va upx_snprintf (char *str, size_t count, const char *format, ...); int upx_vasprintf(char **ptr, const char *format, va_list ap); -int __acc_cdecl_va upx_asprintf(char **ptr, const char *format, ...); +int __acc_cdecl_va upx_asprintf (char **ptr, const char *format, ...); -#if 1 -# undef sprintf -# define sprintf error_sprintf_is_dangerous_use_snprintf -#endif +#undef sprintf +#define sprintf error_sprintf_is_dangerous_use_snprintf +size_t upx_strlen(const char *); + +#undef strlen +#define strlen upx_strlen #ifdef __cplusplus } @@ -55,8 +55,6 @@ int __acc_cdecl_va upx_asprintf(char **ptr, const char *format, ...); #endif /* already included */ - /* vi:ts=4:et:nowrap */ - diff --git a/src/util.cpp b/src/util.cpp index 3adde035..35b0cfce 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -283,7 +283,7 @@ static const char dir_sep[] = "/\\"; #else -static const char dir_sep[] = "/"; +//static const char dir_sep[] = "/"; #define fn_is_drive(s) (0) #define fn_is_sep(c) ((c) == '/') #define fn_skip_drive(s) (s) @@ -319,6 +319,7 @@ bool fn_has_ext(const char *name, const char *ext, bool ignore_case) } +#if 0 // UNUSED void fn_addslash(char *name, bool slash) { char *p; @@ -334,6 +335,7 @@ void fn_addslash(char *name, bool slash) *p = 0; } } +#endif // UNUSED char *fn_strlwr(char *n) @@ -362,6 +364,7 @@ int fn_strcmp(const char *n1, const char *n2) } +#if 0 // UNUSED bool fn_is_same_file(const char *n1, const char *n2) { /* very simple... */ @@ -369,6 +372,7 @@ bool fn_is_same_file(const char *n1, const char *n2) return 1; return 0; } +#endif // UNUSED /*************************************************************************