diff --git a/src/bele.h b/src/bele.h index 965a4586..7eea80cd 100644 --- a/src/bele.h +++ b/src/bele.h @@ -192,7 +192,7 @@ __acc_static_forceinline int sign_extend(unsigned v, unsigned bits) { } __acc_static_forceinline upx_int64_t sign_extend(upx_uint64_t v, unsigned bits) { - const upx_uint64_t sign_bit = UPX_UINT64_C(1) << (bits - 1); + const upx_uint64_t sign_bit = 1ull << (bits - 1); v &= sign_bit | (sign_bit - 1); v |= 0 - (v & sign_bit); return ACC_ICAST(upx_int64_t, v); diff --git a/src/c_init.cpp b/src/c_init.cpp index c5700a31..b8faccb5 100644 --- a/src/c_init.cpp +++ b/src/c_init.cpp @@ -142,13 +142,13 @@ console_t console_init = }; -void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...) +void con_fprintf(FILE *f, const char *format, ...) { va_list args; char buf[80*25]; va_start(args, format); - upx_vsnprintf(buf, sizeof(buf), format,args); + upx_safe_vsnprintf(buf, sizeof(buf), format,args); va_end(args); if (con == me) diff --git a/src/conf.h b/src/conf.h index 52a28457..dfc198f9 100644 --- a/src/conf.h +++ b/src/conf.h @@ -42,14 +42,10 @@ #if !defined(_FILE_OFFSET_BITS) # define _FILE_OFFSET_BITS 64 #endif -// MinGW confusion #if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) # if !defined(_USE_MINGW_ANSI_STDIO) # define _USE_MINGW_ANSI_STDIO 1 # endif -# if !defined(__printf__) -# define __printf__ __gnu_printf__ -# endif #endif #undef NDEBUG @@ -99,6 +95,8 @@ ACC_COMPILE_TIME_ASSERT_HEADER((char)(-1) > 0) // -funsigned-char # pragma warning(disable: 4820) // padding added after data member #endif +#undef snprintf +#undef vsnprintf #define ACC_WANT_ACC_INCD_H 1 #define ACC_WANT_ACC_INCE_H 1 #define ACC_WANT_ACC_LIB_H 1 @@ -115,12 +113,6 @@ typedef acc_uint32_t upx_uint32_t; typedef acc_int64_t upx_int64_t; typedef acc_uint64_t upx_uint64_t; typedef acc_uintptr_t upx_uintptr_t; -#define UPX_INT16_C ACC_INT16_C -#define UPX_UINT16_C ACC_UINT16_C -#define UPX_INT32_C ACC_INT32_C -#define UPX_UINT32_C ACC_UINT32_C -#define UPX_INT64_C ACC_INT64_C -#define UPX_UINT64_C ACC_UINT64_C typedef unsigned char upx_byte; #define upx_bytep upx_byte * @@ -290,14 +282,18 @@ typedef upx_int64_t upx_off_t; #define CLANG_FORMAT_DUMMY_STATEMENT /*empty*/ -#if (ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE) -__acc_static_forceinline void NO_printf(const char *, ...) - __attribute__((__format__(__printf__, 1, 2))); -__acc_static_forceinline void NO_fprintf(FILE *, const char *, ...) - __attribute__((__format__(__printf__, 2, 3))); +#if defined(_WIN32) && defined(__MINGW32__) && defined(__GNUC__) && !defined(__clang__) +# define attribute_format(a,b) __attribute__((__format__(__gnu_printf__,a,b))); +#elif (ACC_CC_CLANG || ACC_CC_GNUC) +# define attribute_format(a,b) __attribute__((__format__(__printf__,a,b))); +#else +# define attribute_format(a,b) /*empty*/ #endif -__acc_static_forceinline void NO_printf(const char *, ...) {} -__acc_static_forceinline void NO_fprintf(FILE *, const char *, ...) {} + +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 *, ...) {} #if !defined(__has_builtin) # define __has_builtin(x) 0 @@ -724,29 +720,13 @@ void printSetNl(int need_nl); void printClearLine(FILE *f = nullptr); void printErr(const char *iname, const Throwable *e); void printUnhandledException(const char *iname, const std::exception *e); -#if (ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE) -void __acc_cdecl_va printErr(const char *iname, const char *format, ...) - __attribute__((__format__(__printf__,2,3))); -void __acc_cdecl_va printWarn(const char *iname, const char *format, ...) - __attribute__((__format__(__printf__,2,3))); -#else -void __acc_cdecl_va printErr(const char *iname, const char *format, ...); -void __acc_cdecl_va printWarn(const char *iname, const char *format, ...); -#endif +void printErr(const char *iname, const char *format, ...) attribute_format(2, 3); +void printWarn(const char *iname, const char *format, ...) attribute_format(2, 3); -#if (ACC_CC_CLANG || ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE) -void __acc_cdecl_va infoWarning(const char *format, ...) - __attribute__((__format__(__printf__,1,2))); -void __acc_cdecl_va infoHeader(const char *format, ...) - __attribute__((__format__(__printf__,1,2))); -void __acc_cdecl_va info(const char *format, ...) - __attribute__((__format__(__printf__,1,2))); -#else -void __acc_cdecl_va infoWarning(const char *format, ...); -void __acc_cdecl_va infoHeader(const char *format, ...); -void __acc_cdecl_va info(const char *format, ...); -#endif -void infoHeader(); +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); void infoWriting(const char *what, long size); diff --git a/src/console.h b/src/console.h index 50b589a9..f8ed94e4 100644 --- a/src/console.h +++ b/src/console.h @@ -122,12 +122,7 @@ typedef struct console_t; -#if defined(__GNUC__) -void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...) - __attribute__((__format__(__printf__,2,3))); -#else -void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...); -#endif +void con_fprintf(FILE *f, const char *format, ...) attribute_format(2, 3); #define FG_BLACK 0x00 diff --git a/src/linker.cpp b/src/linker.cpp index 83798947..2403da5e 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -40,12 +40,12 @@ static bool update_capacity(unsigned size, unsigned *capacity) { return true; } -static void __acc_cdecl_va internal_error(const char *format, ...) { +static void internal_error(const char *format, ...) { static char buf[1024]; va_list ap; va_start(ap, format); - upx_vsnprintf(buf, sizeof(buf), format, ap); + upx_safe_vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); throwInternalError(buf); @@ -426,7 +426,7 @@ void ElfLinker::addLoader(const char *s, va_list ap) { } } -void __acc_cdecl_va ElfLinker::addLoaderVA(const char *s, ...) { +void ElfLinker::addLoaderVA(const char *s, ...) { va_list ap; va_start(ap, s); addLoader(s, ap); @@ -503,8 +503,8 @@ void ElfLinker::dumpSymbol(const Symbol *symbol, unsigned flags, FILE *fp) const if ((flags & 1) && symbol->section->output == nullptr) return; char d0[16 + 1], d1[16 + 1]; - upx_snprintf(d0, sizeof(d0), "%016llx", (upx_uint64_t) symbol->offset); - upx_snprintf(d1, sizeof(d1), "%016llx", (upx_uint64_t) symbol->section->offset); + upx_safe_snprintf(d0, sizeof(d0), "%016llx", (upx_uint64_t) symbol->offset); + upx_safe_snprintf(d1, sizeof(d1), "%016llx", (upx_uint64_t) symbol->section->offset); fprintf(fp, "%-28s 0x%-16s | %-28s 0x%-16s\n", symbol->name, d0, symbol->section->name, d1); } void ElfLinker::dumpSymbols(unsigned flags, FILE *fp) const { @@ -514,7 +514,7 @@ void ElfLinker::dumpSymbols(unsigned flags, FILE *fp) const { // default: dump symbols in used section order for (const Section *section = head; section; section = section->next) { char d1[16 + 1]; - upx_snprintf(d1, sizeof(d1), "%016llx", (upx_uint64_t) section->offset); + upx_safe_snprintf(d1, sizeof(d1), "%016llx", (upx_uint64_t) section->offset); fprintf(fp, "%-42s%-28s 0x%-16s\n", "", section->name, d1); for (unsigned ic = 0; ic < nsymbols; ic++) { const Symbol *symbol = symbols[ic]; diff --git a/src/linker.h b/src/linker.h index 81c3fc75..cae5e8df 100644 --- a/src/linker.h +++ b/src/linker.h @@ -82,10 +82,10 @@ public: // virtual void setLoaderAlignOffset(int phase); virtual int addLoader(const char *sname); void addLoader(const char *s, va_list ap); -#if 1 && (ACC_CC_CLANG || (ACC_CC_GNUC >= 0x040100)) - void __acc_cdecl_va addLoaderVA(const char *s, ...) __attribute__((__sentinel__)); +#if (ACC_CC_CLANG || ACC_CC_GNUC) + void addLoaderVA(const char *s, ...) __attribute__((__sentinel__)); #else - void __acc_cdecl_va addLoaderVA(const char *s, ...); + void addLoaderVA(const char *s, ...); #endif virtual Section *addSection(const char *sname, const void *sdata, int slen, unsigned p2align); virtual int getSection(const char *sname, int *slen = nullptr) const; diff --git a/src/main.cpp b/src/main.cpp index b56f1ac6..ffc00847 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1342,7 +1342,7 @@ void upx_compiler_sanity_check(void) { assert(get_le32(d) == 0xfcfdfeff); assert(bele->get32(d) == 0xfcfdfeff); assert(get_le32_signed(d) == -50462977); - assert(get_le64_signed(d) == UPX_INT64_C(-506097522914230529)); + assert(get_le64_signed(d) == -506097522914230529LL); assert(find_be16(d, 2, 0xfffe) == 0); assert(find_le16(d, 2, 0xfeff) == 0); assert(find_be32(d, 4, 0xfffefdfc) == 0); @@ -1351,7 +1351,7 @@ void upx_compiler_sanity_check(void) { assert(get_be16_signed(d) == 32638); assert(get_be24_signed(d) == 8355453); assert(get_be32_signed(d) == 2138996092); - assert(get_be64_signed(d) == UPX_INT64_C(9186918263483431288)); + assert(get_be64_signed(d) == 9186918263483431288LL); } { unsigned dd; @@ -1574,7 +1574,7 @@ int __acc_cdecl_main main(int argc, char *argv[]) { long long ll = argc < 0 ? 0 : -1; unsigned long long llu = (unsigned long long) ll; char buf[256]; - upx_snprintf(buf, sizeof(buf), ".%d.%ld.%lld.%u.%lu.%llu", -3, -2L, ll, 3U, 2LU, llu); + snprintf(buf, sizeof(buf), ".%d.%ld.%lld.%u.%lu.%llu", -3, -2L, ll, 3U, 2LU, llu); assert(strcmp(buf, ".-3.-2.-1.3.2.18446744073709551615") == 0); } #endif diff --git a/src/msg.cpp b/src/msg.cpp index 83be4e3e..a3f9bbc6 100644 --- a/src/msg.cpp +++ b/src/msg.cpp @@ -91,10 +91,10 @@ static void pr_error(const char *iname, const char *msg, bool is_warning) bool c = acc_isatty(STDERR_FILENO) ? 1 : 0; int fg = con_fg(stderr,FG_BRTRED); - upx_snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),"%s: ", progname); + snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),"%s: ", progname); pr_print(c,buf); //(void)con_fg(stderr,FG_RED); - upx_snprintf(buf,sizeof(buf),"%s: ", iname); + snprintf(buf,sizeof(buf),"%s: ", iname); pr_print(c,buf); //(void)con_fg(stderr,FG_BRTRED); pr_print(c,msg); @@ -112,13 +112,13 @@ void printErr(const char *iname, const Throwable *e) char buf[1024]; size_t l; - upx_snprintf(buf, sizeof(buf), "%s", prettyName(typeid(*e).name())); + snprintf(buf, sizeof(buf), "%s", prettyName(typeid(*e).name())); l = strlen(buf); if (l < sizeof(buf) && e->getMsg()) - upx_snprintf(buf+l, sizeof(buf)-l, ": %s", e->getMsg()); + snprintf(buf+l, sizeof(buf)-l, ": %s", e->getMsg()); l = strlen(buf); if (l < sizeof(buf) && e->getErrno()) { - upx_snprintf(buf+l, sizeof(buf)-l, ": %s", strerror(e->getErrno())); + snprintf(buf+l, sizeof(buf)-l, ": %s", strerror(e->getErrno())); #if 1 // some compilers (e.g. Borland C++) put a trailing '\n' // into strerror() result @@ -131,26 +131,26 @@ void printErr(const char *iname, const Throwable *e) } -void __acc_cdecl_va printErr(const char *iname, const char *format, ...) +void printErr(const char *iname, const char *format, ...) { va_list args; char buf[1024]; va_start(args,format); - upx_vsnprintf(buf,sizeof(buf),format,args); + upx_safe_vsnprintf(buf,sizeof(buf),format,args); va_end(args); pr_error(iname,buf,false); } -void __acc_cdecl_va printWarn(const char *iname, const char *format, ...) +void printWarn(const char *iname, const char *format, ...) { va_list args; char buf[1024]; va_start(args,format); - upx_vsnprintf(buf,sizeof(buf),format,args); + upx_safe_vsnprintf(buf,sizeof(buf),format,args); va_end(args); pr_error(iname,buf,true); @@ -201,21 +201,21 @@ void infoHeader() info_header = 0; } -void __acc_cdecl_va infoHeader(const char *format, ...) +void infoHeader(const char *format, ...) { if (opt->info_mode <= 0) return; va_list args; char buf[1024]; va_start(args,format); - upx_vsnprintf(buf,sizeof(buf),format,args); + upx_safe_vsnprintf(buf,sizeof(buf),format,args); va_end(args); info_print(buf); info_header = 1; } -void __acc_cdecl_va info(const char *format, ...) +void info(const char *format, ...) { if (opt->info_mode <= 0) return; @@ -224,13 +224,13 @@ void __acc_cdecl_va info(const char *format, ...) const int n = 4 * info_header; memset(buf, ' ', n); va_start(args,format); - upx_vsnprintf(buf+n,sizeof(buf)-n,format,args); + upx_safe_vsnprintf(buf+n,sizeof(buf)-n,format,args); va_end(args); info_print(buf); } -void __acc_cdecl_va infoWarning(const char *format, ...) +void infoWarning(const char *format, ...) { if (opt->info_mode <= 0) { @@ -240,7 +240,7 @@ void __acc_cdecl_va infoWarning(const char *format, ...) va_list args; char buf[1024]; va_start(args,format); - upx_vsnprintf(buf,sizeof(buf),format,args); + upx_safe_vsnprintf(buf,sizeof(buf),format,args); va_end(args); info("[WARNING] %s\n", buf); } diff --git a/src/packer.cpp b/src/packer.cpp index e853653a..7a92394e 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -1013,7 +1013,7 @@ void Packer::addLoader(C a, C b, C c, C d, C e, C f, C g, C h, C i, C j) { #undef C #undef N -void __acc_cdecl_va Packer::addLoaderVA(const char *s, ...) { +void Packer::addLoaderVA(const char *s, ...) { va_list ap; va_start(ap, s); linker->addLoader(s, ap); diff --git a/src/packer.h b/src/packer.h index ff00f66a..c091814c 100644 --- a/src/packer.h +++ b/src/packer.h @@ -223,10 +223,10 @@ protected: void addLoader(C, C, C, C, C, C, C, C, C); void addLoader(C, C, C, C, C, C, C, C, C, C); #undef C -#if 1 && (ACC_CC_CLANG || (ACC_CC_GNUC >= 0x040100)) - void __acc_cdecl_va addLoaderVA(const char *s, ...) __attribute__((__sentinel__)); +#if (ACC_CC_CLANG || ACC_CC_GNUC) + void addLoaderVA(const char *s, ...) __attribute__((__sentinel__)); #else - void __acc_cdecl_va addLoaderVA(const char *s, ...); + void addLoaderVA(const char *s, ...); #endif virtual bool hasLoaderSection(const char *name) const; virtual int getLoaderSection(const char *name, int *slen = nullptr) const; diff --git a/src/pefile.cpp b/src/pefile.cpp index f232cfc1..0bc5e53c 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -632,7 +632,7 @@ class PeFile::ImportLinker : public ElfLinkerAMD64 unsigned len = 1 + 2 * strlen(dll) + 1 + 2 * strlen(proc) + 1 + 1; tstr dlln(name_for_dll(dll, first_char)); char *procn = New(char, len); - upx_snprintf(procn, len, "%s%c", (const char*) dlln, separator); + upx_safe_snprintf(procn, len, "%s%c", (const char*) dlln, separator); encode_name(proc, procn + strlen(procn)); return procn; } @@ -741,7 +741,7 @@ public: ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" assert(ordinal > 0 && ordinal < 0x10000); char ord[1+5+1]; - upx_snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal); + upx_safe_snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal); add((const char*) dll, ord, ordinal); } @@ -803,7 +803,7 @@ public: ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char" assert(ordinal > 0 && ordinal < 0x10000); char ord[1+5+1]; - upx_snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal); + upx_safe_snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal); const Section *s = getThunk((const char*) dll, ord, thunk_separator_first); if (s == nullptr @@ -898,7 +898,7 @@ unsigned PeFile::processImports0(ord_mask_t ord_mask) // pass 1 if (u2->ordinal) return 1; if (!u1->shname) return 1; if (!u2->shname) return -1; - rc = (int) (upx_strlen(u1->shname) - upx_strlen(u2->shname)); + rc = (int) (upx_safe_strlen(u1->shname) - upx_safe_strlen(u2->shname)); if (rc) return rc; return strcmp(u1->shname, u2->shname); } @@ -1933,7 +1933,7 @@ void PeFile::processResources(Resource *res) keep_icons = New(char, 1 + iconsin1stdir * 9); *keep_icons = 0; for (unsigned ic = 0; ic < iconsin1stdir; ic++) - upx_snprintf(keep_icons + strlen(keep_icons), 9, "3/%u,", + upx_safe_snprintf(keep_icons + strlen(keep_icons), 9, "3/%u,", get_le16(ibuf.subref("bad resoff %#x", res->offs() + 6 + ic * 14 + 12, 2))); if (*keep_icons) keep_icons[strlen(keep_icons) - 1] = 0; @@ -2131,7 +2131,7 @@ void PeFile::checkHeaderValues(unsigned subsystem, unsigned mask, if ((1u << subsystem) & ~mask) { char buf[100]; - upx_snprintf(buf, sizeof(buf), "PE: subsystem %u is not supported", + upx_safe_snprintf(buf, sizeof(buf), "PE: subsystem %u is not supported", subsystem); throwCantPack(buf); } diff --git a/src/s_vcsa.cpp b/src/s_vcsa.cpp index 87e26d1d..0c91d1f8 100644 --- a/src/s_vcsa.cpp +++ b/src/s_vcsa.cpp @@ -258,10 +258,10 @@ static int init(screen_t *this, int fd) { int attr; Cell a; - upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcsa%d", (int) MINOR(st.st_rdev)); + upx_safe_snprintf(vc_name, sizeof(vc_name), "/dev/vcsa%d", (int) MINOR(st.st_rdev)); this->data->fd = open(vc_name, O_RDWR); if (this->data->fd == -1) { - upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcc/a%d", (int) MINOR(st.st_rdev)); + upx_safe_snprintf(vc_name, sizeof(vc_name), "/dev/vcc/a%d", (int) MINOR(st.st_rdev)); this->data->fd = open(vc_name, O_RDWR); } if (this->data->fd != -1) { diff --git a/src/snprintf.cpp b/src/snprintf.cpp index f1131338..5ac5b33d 100644 --- a/src/snprintf.cpp +++ b/src/snprintf.cpp @@ -1,10 +1,38 @@ +/* snprintf.cpp -- string wrapper + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2021 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2021 Laszlo Molnar + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + */ + #include "conf.h" /************************************************************************* -// UPX version of string functions, with assertions +// UPX version of string functions, with assertions and sane limits **************************************************************************/ -int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap) { +#undef vsnprintf +int upx_safe_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap) { size_t size; // preconditions @@ -17,7 +45,7 @@ int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list a long long n = vsnprintf(str, max_size, format, ap); assert(n >= 0); assert(n < UPX_RSIZE_MAX_STR); - size = (size_t)n + 1; + size = (size_t) n + 1; // postconditions assert(size > 0); @@ -30,17 +58,17 @@ int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list a return ACC_ICONV(int, size - 1); // snprintf() returns length, not size } -int __acc_cdecl_va upx_snprintf(char *str, upx_rsize_t max_size, const char *format, ...) { +int upx_safe_snprintf(char *str, upx_rsize_t max_size, const char *format, ...) { va_list ap; int len; va_start(ap, format); - len = upx_vsnprintf(str, max_size, format, ap); + len = upx_safe_vsnprintf(str, max_size, format, ap); va_end(ap); return len; } -int upx_vasprintf(char **ptr, const char *format, va_list ap) { +int upx_safe_vasprintf(char **ptr, const char *format, va_list ap) { int len; assert(ptr != nullptr); @@ -48,7 +76,7 @@ int upx_vasprintf(char **ptr, const char *format, va_list ap) { va_list ap_copy; va_copy(ap_copy, ap); - len = upx_vsnprintf(nullptr, 0, format, ap_copy); + len = upx_safe_vsnprintf(nullptr, 0, format, ap_copy); va_end(ap_copy); if (len >= 0) { @@ -56,29 +84,41 @@ int upx_vasprintf(char **ptr, const char *format, va_list ap) { assert(*ptr != nullptr); if (*ptr == nullptr) return -1; - int len2 = upx_vsnprintf(*ptr, len + 1, format, ap); + int len2 = upx_safe_vsnprintf(*ptr, len + 1, format, ap); assert(len2 == len); } return len; } -int __acc_cdecl_va upx_asprintf(char **ptr, const char *format, ...) { +int upx_safe_asprintf(char **ptr, const char *format, ...) { va_list ap; int len; va_start(ap, format); - len = upx_vasprintf(ptr, format, ap); + len = upx_safe_vasprintf(ptr, format, ap); va_end(ap); return len; } +char *upx_safe_xprintf(const char *format, ...) { + char *ptr = nullptr; + va_list ap; + int len; + + va_start(ap, format); + len = upx_safe_vasprintf(&ptr, format, ap); + va_end(ap); + UNUSED(len); + assert(ptr != nullptr); + return ptr; +} + #undef strlen -upx_rsize_t upx_strlen(const char *s) { +upx_rsize_t upx_safe_strlen(const char *s) { assert(s != nullptr); size_t len = strlen(s); assert(len < UPX_RSIZE_MAX_STR); return len; } - /* vim:set ts=4 sw=4 et: */ diff --git a/src/snprintf.h b/src/snprintf.h index 35a9d6b8..dfb07b4c 100644 --- a/src/snprintf.h +++ b/src/snprintf.h @@ -29,30 +29,33 @@ #define __UPX_SNPRINTF_H 1 /************************************************************************* -// +// UPX version of string functions, with assertions and sane limits **************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - // info: snprintf() returns length and NOT size, but max_size is indeed size (incl NUL) -int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap); -int __acc_cdecl_va upx_snprintf (char *str, upx_rsize_t max_size, 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, ...); -upx_rsize_t upx_strlen(const char *); +int upx_safe_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap); +int upx_safe_snprintf (char *str, upx_rsize_t max_size, const char *format, ...) attribute_format(3, 4); -#ifdef __cplusplus -} -#endif +// malloc's *ptr +int upx_safe_vasprintf(char **ptr, const char *format, va_list ap); +int upx_safe_asprintf (char **ptr, const char *format, ...) attribute_format(2, 3); + +// returns a malloc'd pointer +char *upx_safe_xprintf(const char *format, ...) attribute_format(1, 2); + +upx_rsize_t upx_safe_strlen(const char *); // globally redirect some functions +#undef snprintf #undef sprintf -#define sprintf error_sprintf_is_dangerous_use_snprintf +#undef vsnprintf +#define snprintf upx_safe_snprintf +#define sprintf ERROR_sprintf_IS_DANGEROUS_USE_snprintf +#define vsnprintf upx_safe_vsnprintf + #undef strlen -#define strlen upx_strlen +#define strlen upx_safe_strlen /************************************************************************* // some unsigned char string support functions @@ -70,7 +73,9 @@ inline int strcasecmp(const unsigned char *s1, const unsigned char *s2) { return strcasecmp((const char *) s1, (const char *) s2); } -inline upx_rsize_t upx_strlen(const unsigned char *s) { return upx_strlen((const char *) s); } +inline upx_rsize_t upx_safe_strlen(const unsigned char *s) { + return upx_safe_strlen((const char *) s); +} #endif /* already included */ diff --git a/src/ui.cpp b/src/ui.cpp index a5f39144..26b8d077 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -140,14 +140,14 @@ static const char *mkline(upx_uint64_t fu_len, upx_uint64_t fc_len, upx_uint64_t if (ratio >= 1000 * 1000) strcpy(r, "overlay"); else - upx_snprintf(r, sizeof(r), "%3u.%02u%%", ratio / 10000, (ratio % 10000) / 100); + upx_safe_snprintf(r, sizeof(r), "%3u.%02u%%", ratio / 10000, (ratio % 10000) / 100); if (decompress) f = "%10lld <-%10lld %7s %15s %s"; else f = "%10lld ->%10lld %7s %15s %s"; center_string(fn, sizeof(fn), format_name); assert(strlen(fn) == 15); - upx_snprintf(buf, sizeof(buf), f, (long long) fu_len, (long long) fc_len, r, fn, filename); + upx_safe_snprintf(buf, sizeof(buf), f, (long long) fu_len, (long long) fc_len, r, fn, filename); UNUSED(u_len); UNUSED(c_len); return buf; @@ -259,8 +259,8 @@ void UiPacker::startCallback(unsigned u_len, unsigned step, int pass, int total_ total_passes /= 10; } while (total_passes > 0); buflen = sizeof(s->msg_buf) - s->bar_pos; - l = upx_snprintf(&s->msg_buf[s->bar_pos], buflen, "%*d/%*d ", s->pass_digits, s->pass, - s->pass_digits, s->total_passes); + l = upx_safe_snprintf(&s->msg_buf[s->bar_pos], buflen, "%*d/%*d ", s->pass_digits, s->pass, + s->pass_digits, s->total_passes); if (l > 0 && s->bar_len - l > 10) { s->bar_len -= l; s->bar_pos += l; @@ -408,8 +408,8 @@ void UiPacker::doCallback(unsigned isize, unsigned osize) { ratio = get_ratio(isize, osize); int buflen = (int) (&s->msg_buf[sizeof(s->msg_buf)] - m); - upx_snprintf(m, buflen, " %3d.%1d%% %c ", ratio / 10000, (ratio % 10000) / 1000, - spinner[s->spin_counter & 3]); + upx_safe_snprintf(m, buflen, " %3d.%1d%% %c ", ratio / 10000, (ratio % 10000) / 1000, + spinner[s->spin_counter & 3]); assert(strlen(s->msg_buf) < 1 + 80); s->pos = pos; @@ -527,8 +527,8 @@ void UiPacker::uiListEnd() { uiUpdate(); } void UiPacker::uiListTotal(bool decompress) { if (opt->verbose >= 1 && total_files >= 2) { char name[32]; - upx_snprintf(name, sizeof(name), "[ %u file%s ]", total_files_done, - total_files_done == 1 ? "" : "s"); + upx_safe_snprintf(name, sizeof(name), "[ %u file%s ]", total_files_done, + total_files_done == 1 ? "" : "s"); con_fprintf( stdout, "%s%s\n", header_line2, mkline(total_fu_len, total_fc_len, total_u_len, total_c_len, "", name, decompress)); diff --git a/src/util.cpp b/src/util.cpp index 4d898ef3..ee58f246 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -28,12 +28,6 @@ #include "conf.h" #include "util.h" -#if (ACC_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1200)) -/* avoid -W4 warnings in */ -#pragma warning(disable : 4032) -/* avoid -W4 warnings in */ -#pragma warning(disable : 4201 4214 4514) -#endif #define ACC_WANT_ACC_INCI_H 1 #include "miniacc.h" #define ACC_WANT_ACCLIB_GETOPT 1 @@ -394,9 +388,9 @@ bool set_method_name(char *buf, size_t size, int method, int level) { r = false; } if (level > 0) - upx_snprintf(buf, size, "%s/%d", alg, level); + upx_safe_snprintf(buf, size, "%s/%d", alg, level); else - upx_snprintf(buf, size, "%s", alg); + upx_safe_snprintf(buf, size, "%s", alg); return r; } @@ -461,7 +455,7 @@ bool maketempname(char *ofilename, size_t size, const char *ifilename, const cha return true; if (!force) break; - upx_snprintf(ofext, 5, ".%03d", ofile); + upx_safe_snprintf(ofext, 5, ".%03d", ofile); } ofilename[0] = 0; @@ -494,7 +488,7 @@ bool makebakname(char *ofilename, size_t size, const char *ifilename, bool force return true; if (!force) break; - upx_snprintf(ofext, 5, ".%03d", ofile); + upx_safe_snprintf(ofext, 5, ".%03d", ofile); } ofilename[0] = 0; diff --git a/src/work.cpp b/src/work.cpp index 28ad5c6a..75d3d8c7 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -33,9 +33,6 @@ #if (ACC_OS_DOS32) && defined(__DJGPP__) #define USE_FTIME 1 -#elif (ACC_OS_WIN32 && ACC_CC_MWERKS) && defined(__MSL__) -#include -#define USE_UTIME 1 #elif ((ACC_OS_WIN32 || ACC_OS_WIN64) && (ACC_CC_INTELC || ACC_CC_MSC)) #define USE__FUTIME 1 #elif (HAVE_UTIME)