From 700c8730cf25401061aa2eb462d6a45dc04f5167 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Tue, 5 Jan 2021 18:52:05 +0100 Subject: [PATCH] Modernize libc usage: stop using `off_t`, use modern printf. C++ 14 is here, and old versions of MSVC and MSVCRT have haunted us long enough. --- src/conf.h | 30 +- src/console.h | 2 +- src/file.cpp | 36 +- src/file.h | 36 +- src/linker.cpp | 2 +- src/main.cpp | 17 +- src/mem.cpp | 2 +- src/miniacc.h | 4 +- src/p_com.cpp | 6 +- src/p_djgpp2.cpp | 15 +- src/p_exe.cpp | 8 +- src/p_ps1.cpp | 2 +- src/p_vmlinz.cpp | 12 +- src/packer.cpp | 12 +- src/packer.h | 11 +- src/pefile.cpp | 2 +- src/snprintf.cpp | 927 +---------------------------------------------- src/ui.cpp | 14 +- src/ui.h | 2 +- 19 files changed, 130 insertions(+), 1010 deletions(-) diff --git a/src/conf.h b/src/conf.h index 1d019ad6..52a28457 100644 --- a/src/conf.h +++ b/src/conf.h @@ -31,7 +31,6 @@ #if defined(__cplusplus) # if (__cplusplus >= 201402L) -# elif defined(__GNUC__) && (__GNUC__+0 == 4) && (__cplusplus >= 201300L) # elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L) # else # error "C++ 14 is required" @@ -43,6 +42,16 @@ #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 @@ -179,6 +188,16 @@ typedef size_t upx_rsize_t; #define UPX_RSIZE_MAX_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!! #define UPX_RSIZE_MAX_STR (1024 * 1024) +// using the system off_t was a bad idea even back in 199x... +typedef upx_int64_t upx_off_t; +#undef off_t +#if 0 +// at some future point we can do this... +#define off_t DO_NOT_USE_off_t +#else +#define off_t upx_off_t +#endif + /************************************************************************* // portab @@ -271,6 +290,15 @@ typedef size_t upx_rsize_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))); +#endif +__acc_static_forceinline void NO_printf(const char *, ...) {} +__acc_static_forceinline void NO_fprintf(FILE *, const char *, ...) {} + #if !defined(__has_builtin) # define __has_builtin(x) 0 #endif diff --git a/src/console.h b/src/console.h index a5aa56bc..50b589a9 100644 --- a/src/console.h +++ b/src/console.h @@ -124,7 +124,7 @@ console_t; #if defined(__GNUC__) void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...) - __attribute__((__format__(printf,2,3))); + __attribute__((__format__(__printf__,2,3))); #else void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...); #endif diff --git a/src/file.cpp b/src/file.cpp index 42782541..c3d7a215 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -170,10 +170,9 @@ void FileBase::write(const void *buf, int len) } -off_t FileBase::seek(upx_int64_t off64, int whence) +upx_off_t FileBase::seek(upx_off_t off, int whence) { - mem_size_assert(1, off64 >= 0 ? off64 : -off64); // sanity check - off_t off = ACC_ICONV(off_t, off64); + mem_size_assert(1, off >= 0 ? off : -off); // sanity check if (!isOpen()) throwIOException("bad seek 1"); if (whence == SEEK_SET) { @@ -193,24 +192,24 @@ off_t FileBase::seek(upx_int64_t off64, int whence) } -off_t FileBase::tell() const +upx_off_t FileBase::tell() const { if (!isOpen()) throwIOException("bad tell"); - off_t l = ::lseek(_fd, 0, SEEK_CUR); + upx_off_t l = ::lseek(_fd, 0, SEEK_CUR); if (l < 0) throwIOException("tell error",errno); return l - _offset; } -void FileBase::set_extent(off_t offset, off_t length) +void FileBase::set_extent(upx_off_t offset, upx_off_t length) { _offset = offset; _length = length; } -off_t FileBase::st_size() const +upx_off_t FileBase::st_size() const { return _length; } @@ -289,21 +288,21 @@ int InputFile::readx(MemBuffer &buf, int len) } -off_t InputFile::seek(upx_int64_t off64, int whence) +upx_off_t InputFile::seek(upx_off_t off, int whence) { - off_t pos = super::seek(off64, whence); + upx_off_t pos = super::seek(off, whence); if (_length < pos) throwIOException("bad seek 4"); return pos; } -off_t InputFile::tell() const +upx_off_t InputFile::tell() const { return super::tell(); } -off_t InputFile::st_size_orig() const +upx_off_t InputFile::st_size_orig() const { return _length_orig; } @@ -373,7 +372,7 @@ void OutputFile::write(const void *buf, int len) bytes_written += len; } -off_t OutputFile::st_size() const +upx_off_t OutputFile::st_size() const { if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid return bytes_written; // too big if seek()+write() instead of rewrite() @@ -406,10 +405,9 @@ void OutputFile::rewrite(const void *buf, int len) bytes_written -= len; // restore } -off_t OutputFile::seek(upx_int64_t off64, int whence) +upx_off_t OutputFile::seek(upx_off_t off, int whence) { - mem_size_assert(1, off64 >= 0 ? off64 : -off64); // sanity check - off_t off = ACC_ICONV(off_t, off64); + mem_size_assert(1, off >= 0 ? off : -off); // sanity check assert(!opt->to_stdout); switch (whence) { case SEEK_SET: { @@ -436,20 +434,20 @@ off_t OutputFile::seek(upx_int64_t off64, int whence) // return infile.read(buf, len); //} -void OutputFile::set_extent(off_t offset, off_t length) +void OutputFile::set_extent(upx_off_t offset, upx_off_t length) { super::set_extent(offset, length); bytes_written = 0; - if (0==offset && (off_t)~0u==length) { + if (0==offset && (upx_off_t)~0u==length) { if (::fstat(_fd, &st) != 0) throwIOException(_name, errno); _length = st.st_size - offset; } } -off_t OutputFile::unset_extent() +upx_off_t OutputFile::unset_extent() { - off_t l = ::lseek(_fd, 0, SEEK_END); + upx_off_t l = ::lseek(_fd, 0, SEEK_END); if (l < 0) throwIOException("lseek error", errno); _offset = 0; diff --git a/src/file.h b/src/file.h index 306cdb87..84baa0bd 100644 --- a/src/file.h +++ b/src/file.h @@ -59,24 +59,24 @@ public: virtual bool isOpen() const { return _fd >= 0; } int getFd() const { return _fd; } const char *getName() const { return _name; } - virtual off_t st_size() const; // { return _length; } - virtual void set_extent(off_t offset, off_t length); + virtual upx_off_t st_size() const; // { return _length; } + virtual void set_extent(upx_off_t offset, upx_off_t length); protected: bool do_sopen(); virtual int read(void *buf, int len); virtual int readx(void *buf, int len); virtual void write(const void *buf, int len); - virtual off_t seek(upx_int64_t off, int whence); - virtual off_t tell() const; + virtual upx_off_t seek(upx_off_t off, int whence); + virtual upx_off_t tell() const; int _fd; int _flags; int _shflags; int _mode; const char *_name; - off_t _offset; - off_t _length; + upx_off_t _offset; + upx_off_t _length; public: struct stat st; }; @@ -106,11 +106,11 @@ public: virtual int read(MemBuffer &buf, int len); virtual int readx(MemBuffer &buf, int len); - virtual off_t seek(upx_int64_t off, int whence); - virtual off_t tell() const; - virtual off_t st_size_orig() const; + virtual upx_off_t seek(upx_off_t off, int whence); + virtual upx_off_t tell() const; + virtual upx_off_t st_size_orig() const; protected: - off_t _length_orig; + upx_off_t _length_orig; }; @@ -135,21 +135,21 @@ public: virtual void write(const void *buf, int len); virtual void write(const MemBuffer *buf, int len); virtual void write(const MemBuffer &buf, int len); - virtual void set_extent(off_t offset, off_t length); - virtual off_t unset_extent(); // returns actual length + virtual void set_extent(upx_off_t offset, upx_off_t length); + virtual upx_off_t unset_extent(); // returns actual length - off_t getBytesWritten() const { return bytes_written; } - virtual off_t st_size() const; // { return _length; } + upx_off_t getBytesWritten() const { return bytes_written; } + virtual upx_off_t st_size() const; // { return _length; } // FIXME - these won't work when using the '--stdout' option - virtual off_t seek(upx_int64_t off, int whence); + virtual upx_off_t seek(upx_off_t off, int whence); virtual void rewrite(const void *buf, int len); // util static void dump(const char *name, const void *buf, int len, int flags=-1); protected: - off_t bytes_written; + upx_off_t bytes_written; }; @@ -172,13 +172,13 @@ public: virtual void write(const void *buf, int len); - off_t getBytesWritten() const { return bytes_written; } + upx_off_t getBytesWritten() const { return bytes_written; } protected: upx_bytep b; unsigned b_size; unsigned b_pos; - off_t bytes_written; + upx_off_t bytes_written; }; #endif /* if 0 */ diff --git a/src/linker.cpp b/src/linker.cpp index 60413e17..83798947 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -45,7 +45,7 @@ static void __acc_cdecl_va internal_error(const char *format, ...) { va_list ap; va_start(ap, format); - vsnprintf(buf, sizeof(buf), format, ap); + upx_vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); throwInternalError(buf); diff --git a/src/main.cpp b/src/main.cpp index 3b12f043..b56f1ac6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1272,12 +1272,6 @@ void upx_compiler_sanity_check(void) { COMPILE_TIME_ASSERT(sizeof(long) >= 4) COMPILE_TIME_ASSERT(sizeof(void *) >= 4) - COMPILE_TIME_ASSERT(sizeof(off_t) >= sizeof(long)) - COMPILE_TIME_ASSERT(((off_t) -1) < 0) -#if (ACC_OS_POSIX_DARWIN || ACC_OS_POSIX_LINUX) - COMPILE_TIME_ASSERT(sizeof(off_t) >= 8) -#endif - COMPILE_TIME_ASSERT(sizeof(BE16) == 2) COMPILE_TIME_ASSERT(sizeof(BE32) == 4) COMPILE_TIME_ASSERT(sizeof(BE64) == 8) @@ -1574,6 +1568,17 @@ int __acc_cdecl_main main(int argc, char *argv[]) { // srand((int) time(nullptr)); srand((int) clock()); +#if defined(_WIN32) || 1 + // runtime check that Win32/MinGW works as expected + { + 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); + assert(strcmp(buf, ".-3.-2.-1.3.2.18446744073709551615") == 0); + } +#endif + int r = upx_main(argc, argv); #if 0 && defined(__GLIBC__) diff --git a/src/mem.cpp b/src/mem.cpp index 5831b889..7a3abaa3 100644 --- a/src/mem.cpp +++ b/src/mem.cpp @@ -35,7 +35,7 @@ **************************************************************************/ #if defined(__SANITIZE_ADDRESS__) -__acc_static_forceinline bool use_simple_mcheck() { return false; } +__acc_static_forceinline constexpr bool use_simple_mcheck() { return false; } #elif (WITH_VALGRIND) && defined(RUNNING_ON_VALGRIND) static int use_simple_mcheck_flag = -1; __acc_static_noinline void use_simple_mcheck_init() diff --git a/src/miniacc.h b/src/miniacc.h index 055f62ec..941dd6f9 100644 --- a/src/miniacc.h +++ b/src/miniacc.h @@ -3841,8 +3841,8 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6 # undef HAVE_SNPRINTF # undef HAVE_VSNPRINTF # else -# define snprintf _snprintf -# define vsnprintf _vsnprintf +//# define snprintf _snprintf +//# define vsnprintf _vsnprintf # endif #elif (ACC_OS_WIN32 && ACC_LIBC_MSL) # if (__MSL__ < 0x8000ul) diff --git a/src/p_com.cpp b/src/p_com.cpp index cc50352b..594ac27e 100644 --- a/src/p_com.cpp +++ b/src/p_com.cpp @@ -223,7 +223,7 @@ int PackCom::canUnpack() { if (!readPackHeader(128)) return false; - if (file_size <= (off_t) ph.c_len) + if (file_size_u <= ph.c_len) return false; return true; } @@ -243,8 +243,8 @@ void PackCom::unpack(OutputFile *fo) fi->readx(ibuf,file_size); // get compressed data offset - int e_len = ph.buf_offset + ph.getPackHeaderSize(); - if (file_size <= e_len + (off_t)ph.c_len) + unsigned e_len = ph.buf_offset + ph.getPackHeaderSize(); + if (file_size_u <= e_len + ph.c_len) throwCantUnpack("file damaged"); // decompress diff --git a/src/p_djgpp2.cpp b/src/p_djgpp2.cpp index a51198fb..4af9a34a 100644 --- a/src/p_djgpp2.cpp +++ b/src/p_djgpp2.cpp @@ -161,24 +161,25 @@ static bool is_dlm(InputFile *fi, unsigned coff_offset) static void handle_allegropak(InputFile *fi, OutputFile *fo) { - unsigned char buf[0x4000]; + unsigned char b[8]; int pfsize = 0; try { fi->seek(-8, SEEK_END); - fi->readx(buf, 8); - if (memcmp(buf, "slh+", 4) != 0) + fi->readx(b, 8); + if (memcmp(b, "slh+", 4) != 0) return; - pfsize = get_be32_signed(buf+4); - if (pfsize <= 8 || pfsize >= (off_t) fi->st.st_size) + pfsize = get_be32_signed(b+4); + if (pfsize <= 8 || pfsize >= fi->st.st_size) return; - fi->seek(-(off_t)pfsize, SEEK_END); + fi->seek(-pfsize, SEEK_END); } catch (const IOException&) { return; } + MemBuffer buf(0x4000); while (pfsize > 0) { - const int len = UPX_MIN(pfsize, (int)sizeof(buf)); + const int len = UPX_MIN(pfsize, (int)buf.getSize()); fi->readx(buf, len); fo->write(buf, len); pfsize -= len; diff --git a/src/p_exe.cpp b/src/p_exe.cpp index 21c3fe6f..3f700c95 100644 --- a/src/p_exe.cpp +++ b/src/p_exe.cpp @@ -286,10 +286,10 @@ int PackExe::readFileHeader() } ih_imagesize = ih_exesize - ih.headsize16*16; ih_overlay = file_size - ih_exesize; - if (file_size < (int)sizeof(ih) + if (file_size_u < sizeof(ih) || ((ih.m512 | ih.p512) && ih.m512+ih.p512*512u < sizeof (ih))) throwCantPack("illegal exe header"); - if (file_size < (off_t)ih_exesize || ih_imagesize <= 0 || ih_imagesize > ih_exesize) + if (file_size_u < ih_exesize || ih_imagesize <= 0 || ih_imagesize > ih_exesize) throwCantPack("exe header corrupted"); #if 0 printf("dos/exe header: %d %d %d\n", ih_exesize, ih_imagesize, ih_overlay); @@ -674,10 +674,10 @@ int PackExe::canUnpack() { if (!readFileHeader()) return false; - const off_t off = ih.headsize16 * 16; + const unsigned off = ih.headsize16 * 16; fi->seek(off, SEEK_SET); bool b = readPackHeader(4096); - return b && (off + (off_t) ph.c_len <= file_size); + return b && (off + ph.c_len <= file_size_u); } diff --git a/src/p_ps1.cpp b/src/p_ps1.cpp index 30edbef9..8bfef637 100644 --- a/src/p_ps1.cpp +++ b/src/p_ps1.cpp @@ -273,7 +273,7 @@ bool PackPs1::canPack() throwCantPack("unsupported header flags (try --force)"); if (!opt->force && file_size < PS_MIN_SIZE) throwCantPack("file is too small (try --force)"); - if (!opt->force && file_size > (off_t) PS_MAX_SIZE) + if (!opt->force && file_size_u > PS_MAX_SIZE) throwCantPack("file is too big (try --force)"); return true; } diff --git a/src/p_vmlinz.cpp b/src/p_vmlinz.cpp index ea5d06d5..8af47d8d 100644 --- a/src/p_vmlinz.cpp +++ b/src/p_vmlinz.cpp @@ -116,7 +116,7 @@ int PackVmlinuzI386::readFileHeader() return 0; int format = UPX_F_VMLINUZ_i386; - unsigned sys_size = ALIGN_UP((unsigned) file_size, 16u) - setup_size; + unsigned sys_size = ALIGN_UP((unsigned) file_size_u, 16u) - setup_size; const unsigned char *p = (const unsigned char *) &h + 0x1e3; @@ -234,7 +234,7 @@ int PackVmlinuzI386::decompressKernel() } } - checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024)); + checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, 1024LL)); int gzoff = setup_size; if (0x208<=h.version) { @@ -259,7 +259,7 @@ int PackVmlinuzI386::decompressKernel() // try to decompress int klen; int fd; - off_t fd_pos; + upx_off_t fd_pos; for (;;) { klen = -1; @@ -344,7 +344,7 @@ int PackVmlinuzI386::decompressKernel() // some checks if (fd_pos != file_size) { - //printf("fd_pos: %ld, file_size: %ld\n", (long)fd_pos, (long)file_size); + NO_printf("fd_pos: %lld, file_size: %lld\n", fd_pos, file_size); // linux-2.6.21.5/arch/i386/boot/compressed/vmlinux.lds // puts .data.compressed ahead of .text, .rodata, etc; @@ -759,7 +759,7 @@ int PackVmlinuzARMEL::decompressKernel() fi->seek(0, SEEK_SET); fi->readx(obuf, file_size); - //checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024)); + //checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, 1024LL)); // Find head.S: // bl decompress_kernel # 0xeb...... @@ -841,7 +841,7 @@ int PackVmlinuzARMEL::decompressKernel() // try to decompress int klen; int fd; - off_t fd_pos; + upx_off_t fd_pos; for (;;) { klen = -1; diff --git a/src/packer.cpp b/src/packer.cpp index b30145f6..e853653a 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -39,8 +39,10 @@ Packer::Packer(InputFile *f) : bele(nullptr), fi(f), file_size(-1), ph_format(-1), ph_version(-1), uip(nullptr), linker(nullptr), last_patch(nullptr), last_patch_len(0), last_patch_off(0) { + file_size = 0; if (fi != nullptr) file_size = fi->st_size(); + mem_size_assert(1, file_size_u); uip = new UiPacker(this); mem_clear(&ph, sizeof(ph)); } @@ -504,7 +506,7 @@ void Packer::handleStub(InputFile *fif, OutputFile *fo, unsigned size) { } void Packer::checkOverlay(unsigned overlay) { - if ((int) overlay < 0 || (off_t) overlay > file_size) + if ((int) overlay < 0 || overlay > file_size_u) throw OverlayException("invalid overlay size; file is possibly corrupt"); if (overlay == 0) return; @@ -515,7 +517,7 @@ void Packer::checkOverlay(unsigned overlay) { void Packer::copyOverlay(OutputFile *fo, unsigned overlay, MemBuffer *buf, bool do_seek) { assert((int) overlay >= 0); - assert((off_t) overlay < file_size); + assert(overlay < file_size_u); buf->checkState(); if (!fo || overlay == 0) return; @@ -526,7 +528,7 @@ void Packer::copyOverlay(OutputFile *fo, unsigned overlay, MemBuffer *buf, bool } info("Copying overlay: %d bytes", overlay); if (do_seek) - fi->seek(-(off_t) overlay, SEEK_END); + fi->seek(-(upx_off_t) overlay, SEEK_END); // get buffer size, align to improve i/o speed unsigned buf_size = buf->getSize(); @@ -640,9 +642,9 @@ bool Packer::getPackHeader(void *b, int blen, bool allow_incompressible) { return false; if (ph.c_len > ph.u_len || (ph.c_len == ph.u_len && !allow_incompressible) || - (off_t) ph.c_len >= file_size || ph.version <= 0 || ph.version >= 0xff) + ph.c_len >= file_size_u || ph.version <= 0 || ph.version >= 0xff) throwCantUnpack("header corrupted"); - else if ((off_t) ph.u_len > ph.u_file_size) { + else if (ph.u_len > ph.u_file_size) { #if 0 // FIXME: does this check make sense w.r.t. overlays ??? if (ph.format == UPX_F_WIN32_PE || ph.format == UPX_F_DOS_EXE) diff --git a/src/packer.h b/src/packer.h index ca26a89f..ff00f66a 100644 --- a/src/packer.h +++ b/src/packer.h @@ -66,7 +66,7 @@ public: unsigned c_len; unsigned u_adler; unsigned c_adler; - off_t u_file_size; + unsigned u_file_size; int filter; int filter_cto; int n_mru; // FIXME: rename to filter_misc @@ -291,8 +291,13 @@ protected: protected: const N_BELE_RTP::AbstractPolicy *bele = nullptr; // target endianness InputFile *fi = nullptr; - off_t file_size; // will get set by constructor - PackHeader ph; // must be filled by canUnpack() + + union { // unnamed union + upx_int64_t file_size; // will get set by constructor + upx_uint64_t file_size_u; // explicitly unsigned + }; + + PackHeader ph; // must be filled by canUnpack() int ph_format; int ph_version; diff --git a/src/pefile.cpp b/src/pefile.cpp index 99b73f05..f232cfc1 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -2094,7 +2094,7 @@ void PeFile::readSectionHeaders(unsigned objs, unsigned sizeof_ih) } mb_isection.alloc(sizeof(pe_section_t) * objs); isection = (pe_section_t *)mb_isection.getVoidPtr(); - if (file_size < (off_t)(pe_offset + sizeof_ih + sizeof(pe_section_t)*objs)) { + if (file_size_u < pe_offset + sizeof_ih + sizeof(pe_section_t)*objs) { char buf[32]; snprintf(buf, sizeof(buf), "too many sections %d", objs); throwCantPack(buf); } diff --git a/src/snprintf.cpp b/src/snprintf.cpp index 75915269..f1131338 100644 --- a/src/snprintf.cpp +++ b/src/snprintf.cpp @@ -1,776 +1,9 @@ -/* - * Copyright Patrick Powell 1995 - * This code is based on code written by Patrick Powell (papowell@astart.com) - * It may be used for any purpose as long as this notice remains intact - * on all source code distributions - */ - -/************************************************************** - * Original: - * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 - * A bombproof version of doprnt (dopr) included. - * Sigh. This sort of thing is always nasty do deal with. Note that - * the version here does not include floating point... - * - * snprintf() is used instead of sprintf() as it does limit checks - * for string length. This covers a nasty loophole. - * - * The other functions are there to prevent NULL pointers from - * causing nast effects. - * - * More Recently: - * Brandon Long 9/15/96 for mutt 0.43 - * This was ugly. It is still ugly. I opted out of floating point - * numbers, but the formatter understands just about everything - * from the normal C string format, at least as far as I can tell from - * the Solaris 2.5 printf(3S) man page. - * - * Brandon Long 10/22/97 for mutt 0.87.1 - * Ok, added some minimal floating point support, which means this - * probably requires libm on most operating systems. Don't yet - * support the exponent (e,E) and sigfig (g,G). Also, fmtint() - * was pretty badly broken, it just wasn't being exercised in ways - * which showed it, so that's been fixed. Also, formated the code - * to mutt conventions, and removed dead code left over from the - * original. Also, there is now a builtin-test, just compile with: - * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm - * and run snprintf for results. - * - * Thomas Roessler 01/27/98 for mutt 0.89i - * The PGP code was using unsigned hexadecimal formats. - * Unfortunately, unsigned formats simply didn't work. - * - * Michael Elkins 03/05/98 for mutt 0.90.8 - * The original code assumed that both snprintf() and vsnprintf() were - * missing. Some systems only have snprintf() but not vsnprintf(), so - * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. - * - * Andrew Tridgell (tridge@samba.org) Oct 1998 - * fixed handling of %.0f - * added test for HAVE_LONG_DOUBLE - * - * tridge@samba.org, idra@samba.org, April 2001 - * got rid of fcvt code (twas buggy and made testing harder) - * added C99 semantics - * - * markus@oberhumer.com, August 2002 - * large modifications for use in UPX - * - **************************************************************/ - -#if 1 #include "conf.h" -#else -#include -#include -#include -#include -#undef NDEBUG -#include -#endif - -#undef LLONG -#undef ULLONG -#define LLONG upx_int64_t -#define ULLONG upx_uint64_t - -#undef NO_FLOAT -#undef LDOUBLE -#if 1 -#define NO_FLOAT 1 -#define float error no_float -#define double error no_float -#else -#if (HAVE_LONG_DOUBLE) -#define LDOUBLE long double -#else -#define LDOUBLE double -#endif -#endif - -/* - * dopr(): poor man's version of doprintf - */ - -/* format read states */ -#define DP_S_DEFAULT 0 -#define DP_S_FLAGS 1 -#define DP_S_MIN 2 -#define DP_S_DOT 3 -#define DP_S_MAX 4 -#define DP_S_MOD 5 -#define DP_S_CONV 6 -#define DP_S_DONE 7 - -/* format flags - Bits */ -#define DP_F_MINUS (1 << 0) -#define DP_F_PLUS (1 << 1) -#define DP_F_SPACE (1 << 2) -#define DP_F_NUM (1 << 3) -#define DP_F_ZERO (1 << 4) -#define DP_F_UP (1 << 5) -#define DP_F_UNSIGNED (1 << 6) - -/* Length modifier */ -#define DP_C_CHAR 1 -#define DP_C_SHORT 2 -#define DP_C_LONG 3 -#define DP_C_LLONG 4 -#define DP_C_LDOUBLE 5 - -#define char_to_int(p) ((p) - '0') -#undef MAX -#define MAX(p, q) (((p) >= (q)) ? (p) : (q)) /************************************************************************* - // +// UPX version of string functions, with assertions **************************************************************************/ -__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 *currsize, size_t maxsize, const char *strvalue, int strln, - int flags, int min, int max) { - int padlen; /* amount to pad */ - int cnt = 0; - -#ifdef DEBUG_SNPRINTF - printf("fmtstr min=%d max=%d s=[%s]\n", min, max, strvalue); -#endif - assert(strvalue != nullptr); - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - while (cnt < max && padlen > 0) { - dopr_outch(buffer, currsize, maxsize, ' '); - --padlen; - ++cnt; - } - while (cnt < max && *strvalue) { - dopr_outch(buffer, currsize, maxsize, *strvalue); - ++strvalue; - ++cnt; - } - while (cnt < max && padlen < 0) { - 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 *currsize, size_t maxsize, LLONG value, unsigned base, - int min, int max, int flags) { - int signvalue = 0; - ULLONG uvalue; - char convert[64 + 1]; - int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - const char *digits; - - if (min < 0) - min = 0; - if (max < 0) - max = 0; - - uvalue = value; - if (!(flags & DP_F_UNSIGNED)) { - if (value < 0) { - signvalue = '-'; - uvalue = -value; - } else { - if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - } - } - - digits = (flags & DP_F_UP) ? "0123456789ABCDEF" : "0123456789abcdef"; - do { - convert[place] = digits[(unsigned) (uvalue % base)]; - uvalue /= base; - } while (++place < (int) sizeof(convert) - 1 && uvalue); - convert[place] = 0; - - zpadlen = max - place; - spadlen = min - MAX(max, place) - (signvalue ? 1 : 0); - if (zpadlen < 0) - zpadlen = 0; - if (spadlen < 0) - spadlen = 0; - if (flags & DP_F_ZERO) { - zpadlen = MAX(zpadlen, spadlen); - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ - -#ifdef DEBUG_SNPRINTF - printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", zpadlen, spadlen, min, max, place); -#endif - - /* Spaces */ - while (spadlen > 0) { - dopr_outch(buffer, currsize, maxsize, ' '); - --spadlen; - } - - /* Sign */ - if (signvalue) - dopr_outch(buffer, currsize, maxsize, signvalue); - - /* Zeros */ - while (zpadlen > 0) { - dopr_outch(buffer, currsize, maxsize, '0'); - --zpadlen; - } - - /* Digits */ - while (place > 0) - dopr_outch(buffer, currsize, maxsize, convert[--place]); - - /* Left Justified spaces */ - while (spadlen < 0) { - dopr_outch(buffer, currsize, maxsize, ' '); - ++spadlen; - } -} - -/************************************************************************* -// floating format support -**************************************************************************/ - -#if !(NO_FLOAT) - -static LDOUBLE abs_val(LDOUBLE value) { - LDOUBLE result = value; - - if (value < 0) - result = -value; - - return result; -} - -static LDOUBLE POW10(int exp) { - LDOUBLE result = 1; - - while (exp) { - result *= 10; - exp--; - } - - return result; -} - -static LLONG ROUND(LDOUBLE value) { - LLONG intpart; - - intpart = (LLONG) value; - value = value - intpart; - if (value >= 0.5) - intpart++; - - return intpart; -} - -/* a replacement for modf that doesn't need the math library. Should - be portable, but slow */ -static double my_modf(double x0, double *iptr) { - int i; - long l; - double x = x0; - double f = 1.0; - - for (i = 0; i < 100; i++) { - l = (long) x; - if (l <= (x + 1) && l >= (x - 1)) - break; - x *= 0.1; - f *= 10.0; - } - - if (i == 100) { - /* yikes! the number is beyond what we can handle. What do we do? */ - *iptr = 0.0; - return 0; - } - - if (i != 0) { - double i2, ret; - - ret = my_modf(x0 - l * f, &i2); - *iptr = l * f + i2; - return ret; - } - - *iptr = l; - return x - *iptr; -} - -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 fmtfp_index - int signvalue = 0; - double ufvalue; - char iconvert[311 + 1]; - char fconvert[311 + 1]; - int iplace = 0; - int fplace = 0; - int padlen = 0; /* amount to pad */ - int zpadlen = 0; - const char *digits; - int index; - double intpart; - double fracpart; - double temp; - - /* - * AIX manpage says the default is 0, but Solaris says the default - * is 6, and sprintf on AIX defaults to 6 - */ - if (min < 0) - min = 0; - if (max < 0) - max = 6; - - ufvalue = abs_val(fvalue); - - if (fvalue < 0) { - signvalue = '-'; - } else { - if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ - signvalue = '+'; - } else { - if (flags & DP_F_SPACE) - signvalue = ' '; - } - } - - digits = "0123456789ABCDEF"; -#if 0 - digits = (flags & DP_F_UP) ? "0123456789ABCDEF" : "0123456789abcdef"; -#endif - -#if 0 - if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ -#endif - - /* - * Sorry, we only support 16 digits past the decimal because of our - * conversion method - */ - if (max > 16) - max = 16; - - /* We "cheat" by converting the fractional part to integer by - * multiplying by a factor of 10 - */ - - temp = ufvalue; - my_modf(temp, &intpart); - - fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); - - if (fracpart >= POW10(max)) { - intpart++; - fracpart -= POW10(max); - } - - /* Convert integer part */ - do { - temp = intpart; - my_modf(intpart * 0.1, &intpart); - temp = temp * 0.1; - index = (int) ((temp - intpart + 0.05) * 10.0); - /* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ - /* printf ("%llf, %f, %x\n", temp, intpart, index); */ - iconvert[iplace] = digits[index]; - } while (++iplace < (int) sizeof(iconvert) - 1 && intpart); - iconvert[iplace] = 0; - - /* Convert fractional part */ - if (fracpart) { - do { - temp = fracpart; - my_modf(fracpart * 0.1, &fracpart); - temp = temp * 0.1; - index = (int) ((temp - fracpart + 0.05) * 10.0); - /* index = (int) ((((temp/10) -fracpart) +0.05) *10); */ - /* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */ - fconvert[fplace] = digits[index]; - } while (++fplace < (int) sizeof(fconvert) - 1 && fracpart); - } - fconvert[fplace] = 0; - - /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); - zpadlen = max - fplace; - if (zpadlen < 0) - zpadlen = 0; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justifty */ - - if ((flags & DP_F_ZERO) && (padlen > 0)) { - if (signvalue) { - dopr_outch(buffer, currsize, maxsize, signvalue); - --padlen; - signvalue = 0; - } - while (padlen > 0) { - dopr_outch(buffer, currsize, maxsize, '0'); - --padlen; - } - } - while (padlen > 0) { - dopr_outch(buffer, currsize, maxsize, ' '); - --padlen; - } - if (signvalue) - dopr_outch(buffer, currsize, maxsize, signvalue); - - while (iplace > 0) - dopr_outch(buffer, currsize, maxsize, iconvert[--iplace]); - -#ifdef DEBUG_SNPRINTF - printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); -#endif - - /* - * Decimal point. This should probably use locale to find the correct - * char to print out. - */ - if (max > 0) { - dopr_outch(buffer, currsize, maxsize, '.'); - while (fplace > 0) - dopr_outch(buffer, currsize, maxsize, fconvert[--fplace]); - } - while (zpadlen > 0) { - dopr_outch(buffer, currsize, maxsize, '0'); - --zpadlen; - } - while (padlen < 0) { - dopr_outch(buffer, currsize, maxsize, ' '); - ++padlen; - } -#undef index -} - -#endif /* !(NO_FLOAT) */ - -/************************************************************************* -// dopr() -**************************************************************************/ - -static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list args) { - char ch; - LLONG value; -#if !(NO_FLOAT) - LDOUBLE fvalue; -#endif - int min; - int max; - int state; - int flags; - int cflags; - size_t currsize; - - state = DP_S_DEFAULT; - currsize = flags = cflags = min = 0; - max = -1; - ch = *format++; - - while (state != DP_S_DONE) { - unsigned base; - const char *strvalue; - int strln; - - if (ch == '\0') - state = DP_S_DONE; - - switch (state) { - case DP_S_DEFAULT: - if (ch == '%') - state = DP_S_FLAGS; - else - dopr_outch(buffer, &currsize, maxsize, ch); - ch = *format++; - break; - case DP_S_FLAGS: - switch (ch) { - case '-': - flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - flags |= DP_F_ZERO; - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } - break; - case DP_S_MIN: - if (isdigit((unsigned char) ch)) { - min = 10 * min + char_to_int(ch); - ch = *format++; - } else if (ch == '*') { - min = va_arg(args, int); - ch = *format++; - state = DP_S_DOT; - } else { - state = DP_S_DOT; - } - assert(min > 0 - UPX_RSIZE_MAX_STR); - assert(min < UPX_RSIZE_MAX_STR); - break; - case DP_S_DOT: - if (ch == '.') { - state = DP_S_MAX; - ch = *format++; - } else { - state = DP_S_MOD; - } - break; - case DP_S_MAX: - if (isdigit((unsigned char) ch)) { - if (max < 0) - max = 0; - max = 10 * max + char_to_int(ch); - ch = *format++; - } else if (ch == '*') { - max = va_arg(args, int); - ch = *format++; - state = DP_S_MOD; - } else { - state = DP_S_MOD; - } - assert(max > 0 - UPX_RSIZE_MAX_STR); - assert(max < UPX_RSIZE_MAX_STR); - break; - case DP_S_MOD: - switch (ch) { - case 'h': - cflags = DP_C_SHORT; - ch = *format++; - if (ch == 'h') { - cflags = DP_C_CHAR; - ch = *format++; - } - break; - case 'l': - cflags = DP_C_LONG; - ch = *format++; - if (ch == 'l') { - cflags = DP_C_LLONG; - ch = *format++; - } - break; - case 'j': // intmax_t - cflags = DP_C_LLONG; - ch = *format++; - break; - case 'z': // size_t - cflags = sizeof(size_t) == sizeof(LLONG) ? DP_C_LLONG : 0; - ch = *format++; - break; - case 't': // ptrdiff_t - cflags = sizeof(ptrdiff_t) == sizeof(LLONG) ? DP_C_LLONG : 0; - ch = *format++; - break; - case 'L': - cflags = DP_C_LDOUBLE; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; - break; - case DP_S_CONV: - switch (ch) { - case 'd': - case 'i': - if (cflags == DP_C_CHAR) - value = (LLONG)(signed char) va_arg(args, int); - else if (cflags == DP_C_SHORT) - value = (LLONG)(short) va_arg(args, int); - else if (cflags == DP_C_LONG) - value = (LLONG) va_arg(args, long); - else if (cflags == DP_C_LLONG) - value = (LLONG) va_arg(args, LLONG); - else - value = (LLONG) va_arg(args, int); - fmtint(buffer, &currsize, maxsize, value, 10, min, max, flags); - break; - case 'X': - flags |= DP_F_UP; - /*fallthrough*/ - case 'x': - base = 16; - l_fmtuint: - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_CHAR) - value = (ULLONG)(unsigned char) va_arg(args, unsigned); - else if (cflags == DP_C_SHORT) - value = (ULLONG)(unsigned short) va_arg(args, unsigned); - else if (cflags == DP_C_LONG) - value = (ULLONG) va_arg(args, unsigned long); - else if (cflags == DP_C_LLONG) - value = (ULLONG) va_arg(args, ULLONG); - else - value = (ULLONG) va_arg(args, unsigned); - fmtint(buffer, &currsize, maxsize, value, base, min, max, flags); - break; - case 'u': - base = 10; - goto l_fmtuint; - case 'o': - base = 8; - goto l_fmtuint; - case 'c': - // TODO: wint_t - dopr_outch(buffer, &currsize, maxsize, va_arg(args, int)); - break; - case 's': - // TODO: wchar_t - strvalue = va_arg(args, const char *); - if (!strvalue) - strvalue = "(NULL)"; - strln = (int) strlen(strvalue); - if (max == -1) - max = strln; - if (min > 0 && max >= 0 && min > max) - max = min; - fmtstr(buffer, &currsize, maxsize, strvalue, strln, flags, min, max); - break; - case 'p': - strvalue = (const char *) va_arg(args, const void *); - fmtint(buffer, &currsize, maxsize, (LLONG)(upx_uintptr_t) strvalue, 16, min, max, - flags); - break; - case 'n': - if (cflags == DP_C_CHAR) { - signed char *num; - num = va_arg(args, signed char *); - assert(num != nullptr); - *num = (signed char) currsize; - } else if (cflags == DP_C_SHORT) { - short *num; - num = va_arg(args, short *); - assert(num != nullptr); - *num = (short) currsize; - } else if (cflags == DP_C_LONG) { - long *num; - num = va_arg(args, long *); - assert(num != nullptr); - *num = (long) currsize; - } else if (cflags == DP_C_LLONG) { - LLONG *num; - num = va_arg(args, LLONG *); - assert(num != nullptr); - *num = (LLONG) currsize; - } else { - int *num; - num = va_arg(args, int *); - assert(num != nullptr); - *num = (int) currsize; - } - break; - case '%': - dopr_outch(buffer, &currsize, maxsize, ch); - break; -#if !(NO_FLOAT) - case 'F': - flags |= DP_F_UP; - /*fallthrough*/ - case 'f': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - /* um, floating point? */ - fmtfp(buffer, &currsize, maxsize, fvalue, min, max, flags); - break; - case 'E': - flags |= DP_F_UP; - /*fallthrough*/ - case 'e': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - break; - case 'G': - flags |= DP_F_UP; - /*fallthrough*/ - case 'g': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - break; -#else - case 'F': - case 'f': - case 'E': - case 'e': - case 'G': - case 'g': - case 'A': - case 'a': - assert(0); - exit(255); -#endif /* !(NO_FLOAT) */ - default: - /* Unknown, skip */ - break; - } - ch = *format++; - state = DP_S_DEFAULT; - flags = cflags = min = 0; - max = -1; - break; - case DP_S_DONE: - break; - default: - /* hmm? */ - break; /* some picky compilers need this */ - } - } - dopr_outch(buffer, &currsize, maxsize, '\0'); - return currsize; // returns size, not length -} - -/************************************************************************* -// public entries -**************************************************************************/ - -// UPX version with assertions int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap) { size_t size; @@ -781,7 +14,10 @@ int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list a else assert(max_size == 0); - size = dopr(str, max_size, format, ap); + long long n = vsnprintf(str, max_size, format, ap); + assert(n >= 0); + assert(n < UPX_RSIZE_MAX_STR); + size = (size_t)n + 1; // postconditions assert(size > 0); @@ -809,14 +45,12 @@ int upx_vasprintf(char **ptr, const char *format, va_list ap) { assert(ptr != nullptr); *ptr = nullptr; -#if defined(va_copy) + va_list ap_copy; va_copy(ap_copy, ap); len = upx_vsnprintf(nullptr, 0, format, ap_copy); va_end(ap_copy); -#else - len = upx_vsnprintf(nullptr, 0, format, ap); -#endif + if (len >= 0) { *ptr = (char *) malloc(len + 1); assert(*ptr != nullptr); @@ -846,152 +80,5 @@ upx_rsize_t upx_strlen(const char *s) { return len; } -/************************************************************************* - // -**************************************************************************/ - -#if 0 || defined(TEST_SNPRINTF) - -#undef sprintf -#include -#include -#include - -#undef snprintf -#define snprintf upx_snprintf -//int sprintf(char *str,const char *fmt,...); - -int main(void) -{ - char buf1[1024]; - char buf2[1024]; - const char *fp_fmt[] = { - "%1.1f", - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - "%.0f", - "%f", - "-16.16f", - nullptr - }; - const double fp_nums[] = { - 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, - 0.9996, 1.996, 4.136, 0 - }; - const char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - "%d", - nullptr - }; - const int int_nums[] = { -1, 134, 91340, 341, 0203, 0 }; - const char *str_fmt[] = { - "10.5s", - "5.10s", - "10.1s", - "0.10s", - "10.0s", - "1.10s", - "%s", - "%.1s", - "%.10s", - "%10s", - 0 - }; - const char *str_vals[] = {"hello", "a", "", "a longer string", nullptr}; - int x, y; - int fail = 0; - int num = 0; - - printf ("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] ; x++) { - for (y = 0; fp_nums[y] != 0 ; y++) { - int l1 = snprintf(nullptr, 0, fp_fmt[x], fp_nums[y]); - int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); - sprintf (buf2, fp_fmt[x], fp_nums[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", - fp_fmt[x], buf1, buf2); - fail++; - } - if (l1 != l2) { - printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]); - fail++; - } - num++; - } - } - - for (x = 0; int_fmt[x] ; x++) { - for (y = 0; int_nums[y] != 0 ; y++) { - int l1 = snprintf(0, 0, int_fmt[x], int_nums[y]); - int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); - sprintf (buf2, int_fmt[x], int_nums[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", - int_fmt[x], buf1, buf2); - fail++; - } - if (l1 != l2) { - printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]); - fail++; - } - num++; - } - } - - for (x = 0; str_fmt[x] ; x++) { - for (y = 0; str_vals[y] != 0 ; y++) { - int l1 = snprintf(nullptr, 0, str_fmt[x], str_vals[y]); - int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); - sprintf (buf2, str_fmt[x], str_vals[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", - str_fmt[x], buf1, buf2); - fail++; - } - if (l1 != l2) { - printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]); - fail++; - } - num++; - } - } - - printf ("%d tests failed out of %d.\n", fail, num); - - printf("seeing how many digits we support\n"); - { - double v0 = 0.12345678901234567890123456789012345678901; - for (x=0; x<100; x++) { - snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x)); - sprintf(buf2, "%1.1f", v0*pow(10, x)); - if (strcmp(buf1, buf2) != 0) { - printf("we seem to support %d digits\n", x-1); - break; - } - } - } - - return 0; -} -#endif /* SNPRINTF_TEST */ /* vim:set ts=4 sw=4 et: */ diff --git a/src/ui.cpp b/src/ui.cpp index 0ef68407..a5f39144 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -566,11 +566,6 @@ void UiPacker::uiTestTotal() { uiFooter("Tested"); } **************************************************************************/ bool UiPacker::uiFileInfoStart() { -#if defined(_WIN32) // msvcrt -#define PRLLD "I64d" -#else -#define PRLLD "lld" -#endif total_files++; int fg = con_fg(stdout, FG_CYAN); @@ -578,16 +573,15 @@ bool UiPacker::uiFileInfoStart() { fg = con_fg(stdout, fg); UNUSED(fg); if (p->ph.c_len > 0) { - con_fprintf(stdout, " %8" PRLLD " bytes", (long long) p->file_size); + con_fprintf(stdout, " %8llu bytes", p->file_size_u); con_fprintf(stdout, ", compressed by UPX %d, method %d, level %d, filter 0x%02x/0x%02x\n", p->ph.version, p->ph.method, p->ph.level, p->ph.filter, p->ph.filter_cto); return false; } else { - con_fprintf(stdout, " %8" PRLLD " bytes", (long long) p->file_size); + con_fprintf(stdout, " %8llu bytes", p->file_size_u); con_fprintf(stdout, ", not compressed by UPX\n"); return true; } -#undef PRLLD } void UiPacker::uiFileInfoEnd() { uiUpdate(); } @@ -628,8 +622,8 @@ void UiPacker::uiFooter(const char *t) { } } -void UiPacker::uiUpdate(off_t fc_len, off_t fu_len) { - update_fc_len = (fc_len >= 0) ? fc_len : p->file_size; +void UiPacker::uiUpdate(upx_off_t fc_len, upx_off_t fu_len) { + update_fc_len = (fc_len >= 0) ? fc_len : p->file_size_u; update_fu_len = (fu_len >= 0) ? fu_len : p->ph.u_file_size; update_c_len = p->ph.c_len; update_u_len = p->ph.u_len; diff --git a/src/ui.h b/src/ui.h index 43068c08..ad8c5e31 100644 --- a/src/ui.h +++ b/src/ui.h @@ -76,7 +76,7 @@ protected: virtual void doCallback(unsigned isize, unsigned osize); protected: - virtual void uiUpdate(off_t fc_len = -1, off_t fu_len = -1); + virtual void uiUpdate(upx_off_t fc_len = -1, upx_off_t fu_len = -1); public: static void uiHeader();