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.
This commit is contained in:
parent
b4429e1a42
commit
700c8730cf
30
src/conf.h
30
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 <stdio.h> 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
|
||||
|
||||
@ -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
|
||||
|
||||
36
src/file.cpp
36
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;
|
||||
|
||||
36
src/file.h
36
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 */
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
17
src/main.cpp
17
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 <stdio.h> 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__)
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
11
src/packer.h
11
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;
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
927
src/snprintf.cpp
927
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 <blong@fiction.net> 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 <blong@fiction.net> 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 <roessler@guug.de> 01/27/98 for mutt 0.89i
|
||||
* The PGP code was using unsigned hexadecimal formats.
|
||||
* Unfortunately, unsigned formats simply didn't work.
|
||||
*
|
||||
* Michael Elkins <me@cs.hmc.edu> 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 <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#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: */
|
||||
|
||||
14
src/ui.cpp
14
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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user