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:
+29
-1
@@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
# if (__cplusplus >= 201402L)
|
# if (__cplusplus >= 201402L)
|
||||||
# elif defined(__GNUC__) && (__GNUC__+0 == 4) && (__cplusplus >= 201300L)
|
|
||||||
# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L)
|
# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L)
|
||||||
# else
|
# else
|
||||||
# error "C++ 14 is required"
|
# error "C++ 14 is required"
|
||||||
@@ -43,6 +42,16 @@
|
|||||||
#if !defined(_FILE_OFFSET_BITS)
|
#if !defined(_FILE_OFFSET_BITS)
|
||||||
# define _FILE_OFFSET_BITS 64
|
# define _FILE_OFFSET_BITS 64
|
||||||
#endif
|
#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
|
#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_MEM (768 * 1024 * 1024) // DO NOT CHANGE !!!
|
||||||
#define UPX_RSIZE_MAX_STR (1024 * 1024)
|
#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
|
// portab
|
||||||
@@ -271,6 +290,15 @@ typedef size_t upx_rsize_t;
|
|||||||
|
|
||||||
#define CLANG_FORMAT_DUMMY_STATEMENT /*empty*/
|
#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)
|
#if !defined(__has_builtin)
|
||||||
# define __has_builtin(x) 0
|
# define __has_builtin(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -124,7 +124,7 @@ console_t;
|
|||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...)
|
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...)
|
||||||
__attribute__((__format__(printf,2,3)));
|
__attribute__((__format__(__printf__,2,3)));
|
||||||
#else
|
#else
|
||||||
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...);
|
void __acc_cdecl_va con_fprintf(FILE *f, const char *format, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+17
-19
@@ -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
|
mem_size_assert(1, off >= 0 ? off : -off); // sanity check
|
||||||
off_t off = ACC_ICONV(off_t, off64);
|
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throwIOException("bad seek 1");
|
throwIOException("bad seek 1");
|
||||||
if (whence == SEEK_SET) {
|
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())
|
if (!isOpen())
|
||||||
throwIOException("bad tell");
|
throwIOException("bad tell");
|
||||||
off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
upx_off_t l = ::lseek(_fd, 0, SEEK_CUR);
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
throwIOException("tell error",errno);
|
throwIOException("tell error",errno);
|
||||||
return l - _offset;
|
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;
|
_offset = offset;
|
||||||
_length = length;
|
_length = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t FileBase::st_size() const
|
upx_off_t FileBase::st_size() const
|
||||||
{
|
{
|
||||||
return _length;
|
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)
|
if (_length < pos)
|
||||||
throwIOException("bad seek 4");
|
throwIOException("bad seek 4");
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
off_t InputFile::tell() const
|
upx_off_t InputFile::tell() const
|
||||||
{
|
{
|
||||||
return super::tell();
|
return super::tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t InputFile::st_size_orig() const
|
upx_off_t InputFile::st_size_orig() const
|
||||||
{
|
{
|
||||||
return _length_orig;
|
return _length_orig;
|
||||||
}
|
}
|
||||||
@@ -373,7 +372,7 @@ void OutputFile::write(const void *buf, int len)
|
|||||||
bytes_written += 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
|
if (opt->to_stdout) { // might be a pipe ==> .st_size is invalid
|
||||||
return bytes_written; // too big if seek()+write() instead of rewrite()
|
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
|
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
|
mem_size_assert(1, off >= 0 ? off : -off); // sanity check
|
||||||
off_t off = ACC_ICONV(off_t, off64);
|
|
||||||
assert(!opt->to_stdout);
|
assert(!opt->to_stdout);
|
||||||
switch (whence) {
|
switch (whence) {
|
||||||
case SEEK_SET: {
|
case SEEK_SET: {
|
||||||
@@ -436,20 +434,20 @@ off_t OutputFile::seek(upx_int64_t off64, int whence)
|
|||||||
// return infile.read(buf, len);
|
// 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);
|
super::set_extent(offset, length);
|
||||||
bytes_written = 0;
|
bytes_written = 0;
|
||||||
if (0==offset && (off_t)~0u==length) {
|
if (0==offset && (upx_off_t)~0u==length) {
|
||||||
if (::fstat(_fd, &st) != 0)
|
if (::fstat(_fd, &st) != 0)
|
||||||
throwIOException(_name, errno);
|
throwIOException(_name, errno);
|
||||||
_length = st.st_size - offset;
|
_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)
|
if (l < 0)
|
||||||
throwIOException("lseek error", errno);
|
throwIOException("lseek error", errno);
|
||||||
_offset = 0;
|
_offset = 0;
|
||||||
|
|||||||
+18
-18
@@ -59,24 +59,24 @@ public:
|
|||||||
virtual bool isOpen() const { return _fd >= 0; }
|
virtual bool isOpen() const { return _fd >= 0; }
|
||||||
int getFd() const { return _fd; }
|
int getFd() const { return _fd; }
|
||||||
const char *getName() const { return _name; }
|
const char *getName() const { return _name; }
|
||||||
virtual off_t st_size() const; // { return _length; }
|
virtual upx_off_t st_size() const; // { return _length; }
|
||||||
virtual void set_extent(off_t offset, off_t length);
|
virtual void set_extent(upx_off_t offset, upx_off_t length);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool do_sopen();
|
bool do_sopen();
|
||||||
virtual int read(void *buf, int len);
|
virtual int read(void *buf, int len);
|
||||||
virtual int readx(void *buf, int len);
|
virtual int readx(void *buf, int len);
|
||||||
virtual void write(const void *buf, int len);
|
virtual void write(const void *buf, int len);
|
||||||
virtual off_t seek(upx_int64_t off, int whence);
|
virtual upx_off_t seek(upx_off_t off, int whence);
|
||||||
virtual off_t tell() const;
|
virtual upx_off_t tell() const;
|
||||||
|
|
||||||
int _fd;
|
int _fd;
|
||||||
int _flags;
|
int _flags;
|
||||||
int _shflags;
|
int _shflags;
|
||||||
int _mode;
|
int _mode;
|
||||||
const char *_name;
|
const char *_name;
|
||||||
off_t _offset;
|
upx_off_t _offset;
|
||||||
off_t _length;
|
upx_off_t _length;
|
||||||
public:
|
public:
|
||||||
struct stat st;
|
struct stat st;
|
||||||
};
|
};
|
||||||
@@ -106,11 +106,11 @@ public:
|
|||||||
virtual int read(MemBuffer &buf, int len);
|
virtual int read(MemBuffer &buf, int len);
|
||||||
virtual int readx(MemBuffer &buf, int len);
|
virtual int readx(MemBuffer &buf, int len);
|
||||||
|
|
||||||
virtual off_t seek(upx_int64_t off, int whence);
|
virtual upx_off_t seek(upx_off_t off, int whence);
|
||||||
virtual off_t tell() const;
|
virtual upx_off_t tell() const;
|
||||||
virtual off_t st_size_orig() const;
|
virtual upx_off_t st_size_orig() const;
|
||||||
protected:
|
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 void *buf, int len);
|
||||||
virtual void write(const MemBuffer *buf, int len);
|
virtual void write(const MemBuffer *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 void set_extent(upx_off_t offset, upx_off_t length);
|
||||||
virtual off_t unset_extent(); // returns actual length
|
virtual upx_off_t unset_extent(); // returns actual length
|
||||||
|
|
||||||
off_t getBytesWritten() const { return bytes_written; }
|
upx_off_t getBytesWritten() const { return bytes_written; }
|
||||||
virtual off_t st_size() const; // { return _length; }
|
virtual upx_off_t st_size() const; // { return _length; }
|
||||||
|
|
||||||
// FIXME - these won't work when using the '--stdout' option
|
// 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);
|
virtual void rewrite(const void *buf, int len);
|
||||||
|
|
||||||
// util
|
// util
|
||||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
off_t bytes_written;
|
upx_off_t bytes_written;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -172,13 +172,13 @@ public:
|
|||||||
|
|
||||||
virtual void write(const void *buf, int len);
|
virtual void write(const void *buf, int len);
|
||||||
|
|
||||||
off_t getBytesWritten() const { return bytes_written; }
|
upx_off_t getBytesWritten() const { return bytes_written; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
upx_bytep b;
|
upx_bytep b;
|
||||||
unsigned b_size;
|
unsigned b_size;
|
||||||
unsigned b_pos;
|
unsigned b_pos;
|
||||||
off_t bytes_written;
|
upx_off_t bytes_written;
|
||||||
};
|
};
|
||||||
#endif /* if 0 */
|
#endif /* if 0 */
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -45,7 +45,7 @@ static void __acc_cdecl_va internal_error(const char *format, ...) {
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
vsnprintf(buf, sizeof(buf), format, ap);
|
upx_vsnprintf(buf, sizeof(buf), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
throwInternalError(buf);
|
throwInternalError(buf);
|
||||||
|
|||||||
+11
-6
@@ -1272,12 +1272,6 @@ void upx_compiler_sanity_check(void) {
|
|||||||
COMPILE_TIME_ASSERT(sizeof(long) >= 4)
|
COMPILE_TIME_ASSERT(sizeof(long) >= 4)
|
||||||
COMPILE_TIME_ASSERT(sizeof(void *) >= 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(BE16) == 2)
|
||||||
COMPILE_TIME_ASSERT(sizeof(BE32) == 4)
|
COMPILE_TIME_ASSERT(sizeof(BE32) == 4)
|
||||||
COMPILE_TIME_ASSERT(sizeof(BE64) == 8)
|
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) time(nullptr));
|
||||||
srand((int) clock());
|
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);
|
int r = upx_main(argc, argv);
|
||||||
|
|
||||||
#if 0 && defined(__GLIBC__)
|
#if 0 && defined(__GLIBC__)
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#if defined(__SANITIZE_ADDRESS__)
|
#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)
|
#elif (WITH_VALGRIND) && defined(RUNNING_ON_VALGRIND)
|
||||||
static int use_simple_mcheck_flag = -1;
|
static int use_simple_mcheck_flag = -1;
|
||||||
__acc_static_noinline void use_simple_mcheck_init()
|
__acc_static_noinline void use_simple_mcheck_init()
|
||||||
|
|||||||
+2
-2
@@ -3841,8 +3841,8 @@ ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(acc_int_fast64_t) == sizeof(acc_uint_fast6
|
|||||||
# undef HAVE_SNPRINTF
|
# undef HAVE_SNPRINTF
|
||||||
# undef HAVE_VSNPRINTF
|
# undef HAVE_VSNPRINTF
|
||||||
# else
|
# else
|
||||||
# define snprintf _snprintf
|
//# define snprintf _snprintf
|
||||||
# define vsnprintf _vsnprintf
|
//# define vsnprintf _vsnprintf
|
||||||
# endif
|
# endif
|
||||||
#elif (ACC_OS_WIN32 && ACC_LIBC_MSL)
|
#elif (ACC_OS_WIN32 && ACC_LIBC_MSL)
|
||||||
# if (__MSL__ < 0x8000ul)
|
# if (__MSL__ < 0x8000ul)
|
||||||
|
|||||||
+3
-3
@@ -223,7 +223,7 @@ int PackCom::canUnpack()
|
|||||||
{
|
{
|
||||||
if (!readPackHeader(128))
|
if (!readPackHeader(128))
|
||||||
return false;
|
return false;
|
||||||
if (file_size <= (off_t) ph.c_len)
|
if (file_size_u <= ph.c_len)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -243,8 +243,8 @@ void PackCom::unpack(OutputFile *fo)
|
|||||||
fi->readx(ibuf,file_size);
|
fi->readx(ibuf,file_size);
|
||||||
|
|
||||||
// get compressed data offset
|
// get compressed data offset
|
||||||
int e_len = ph.buf_offset + ph.getPackHeaderSize();
|
unsigned e_len = ph.buf_offset + ph.getPackHeaderSize();
|
||||||
if (file_size <= e_len + (off_t)ph.c_len)
|
if (file_size_u <= e_len + ph.c_len)
|
||||||
throwCantUnpack("file damaged");
|
throwCantUnpack("file damaged");
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
|
|||||||
+8
-7
@@ -161,24 +161,25 @@ static bool is_dlm(InputFile *fi, unsigned coff_offset)
|
|||||||
|
|
||||||
static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
||||||
{
|
{
|
||||||
unsigned char buf[0x4000];
|
unsigned char b[8];
|
||||||
int pfsize = 0;
|
int pfsize = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fi->seek(-8, SEEK_END);
|
fi->seek(-8, SEEK_END);
|
||||||
fi->readx(buf, 8);
|
fi->readx(b, 8);
|
||||||
if (memcmp(buf, "slh+", 4) != 0)
|
if (memcmp(b, "slh+", 4) != 0)
|
||||||
return;
|
return;
|
||||||
pfsize = get_be32_signed(buf+4);
|
pfsize = get_be32_signed(b+4);
|
||||||
if (pfsize <= 8 || pfsize >= (off_t) fi->st.st_size)
|
if (pfsize <= 8 || pfsize >= fi->st.st_size)
|
||||||
return;
|
return;
|
||||||
fi->seek(-(off_t)pfsize, SEEK_END);
|
fi->seek(-pfsize, SEEK_END);
|
||||||
} catch (const IOException&) {
|
} catch (const IOException&) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
MemBuffer buf(0x4000);
|
||||||
while (pfsize > 0)
|
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);
|
fi->readx(buf, len);
|
||||||
fo->write(buf, len);
|
fo->write(buf, len);
|
||||||
pfsize -= len;
|
pfsize -= len;
|
||||||
|
|||||||
+4
-4
@@ -286,10 +286,10 @@ int PackExe::readFileHeader()
|
|||||||
}
|
}
|
||||||
ih_imagesize = ih_exesize - ih.headsize16*16;
|
ih_imagesize = ih_exesize - ih.headsize16*16;
|
||||||
ih_overlay = file_size - ih_exesize;
|
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)))
|
|| ((ih.m512 | ih.p512) && ih.m512+ih.p512*512u < sizeof (ih)))
|
||||||
throwCantPack("illegal exe header");
|
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");
|
throwCantPack("exe header corrupted");
|
||||||
#if 0
|
#if 0
|
||||||
printf("dos/exe header: %d %d %d\n", ih_exesize, ih_imagesize, ih_overlay);
|
printf("dos/exe header: %d %d %d\n", ih_exesize, ih_imagesize, ih_overlay);
|
||||||
@@ -674,10 +674,10 @@ int PackExe::canUnpack()
|
|||||||
{
|
{
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
const off_t off = ih.headsize16 * 16;
|
const unsigned off = ih.headsize16 * 16;
|
||||||
fi->seek(off, SEEK_SET);
|
fi->seek(off, SEEK_SET);
|
||||||
bool b = readPackHeader(4096);
|
bool b = readPackHeader(4096);
|
||||||
return b && (off + (off_t) ph.c_len <= file_size);
|
return b && (off + ph.c_len <= file_size_u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -273,7 +273,7 @@ bool PackPs1::canPack()
|
|||||||
throwCantPack("unsupported header flags (try --force)");
|
throwCantPack("unsupported header flags (try --force)");
|
||||||
if (!opt->force && file_size < PS_MIN_SIZE)
|
if (!opt->force && file_size < PS_MIN_SIZE)
|
||||||
throwCantPack("file is too small (try --force)");
|
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)");
|
throwCantPack("file is too big (try --force)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -116,7 +116,7 @@ int PackVmlinuzI386::readFileHeader()
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int format = UPX_F_VMLINUZ_i386;
|
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;
|
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;
|
int gzoff = setup_size;
|
||||||
if (0x208<=h.version) {
|
if (0x208<=h.version) {
|
||||||
@@ -259,7 +259,7 @@ int PackVmlinuzI386::decompressKernel()
|
|||||||
// try to decompress
|
// try to decompress
|
||||||
int klen;
|
int klen;
|
||||||
int fd;
|
int fd;
|
||||||
off_t fd_pos;
|
upx_off_t fd_pos;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
klen = -1;
|
klen = -1;
|
||||||
@@ -344,7 +344,7 @@ int PackVmlinuzI386::decompressKernel()
|
|||||||
// some checks
|
// some checks
|
||||||
if (fd_pos != file_size)
|
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
|
// linux-2.6.21.5/arch/i386/boot/compressed/vmlinux.lds
|
||||||
// puts .data.compressed ahead of .text, .rodata, etc;
|
// puts .data.compressed ahead of .text, .rodata, etc;
|
||||||
@@ -759,7 +759,7 @@ int PackVmlinuzARMEL::decompressKernel()
|
|||||||
fi->seek(0, SEEK_SET);
|
fi->seek(0, SEEK_SET);
|
||||||
fi->readx(obuf, file_size);
|
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:
|
// Find head.S:
|
||||||
// bl decompress_kernel # 0xeb......
|
// bl decompress_kernel # 0xeb......
|
||||||
@@ -841,7 +841,7 @@ int PackVmlinuzARMEL::decompressKernel()
|
|||||||
// try to decompress
|
// try to decompress
|
||||||
int klen;
|
int klen;
|
||||||
int fd;
|
int fd;
|
||||||
off_t fd_pos;
|
upx_off_t fd_pos;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
klen = -1;
|
klen = -1;
|
||||||
|
|||||||
+7
-5
@@ -39,8 +39,10 @@
|
|||||||
Packer::Packer(InputFile *f)
|
Packer::Packer(InputFile *f)
|
||||||
: bele(nullptr), fi(f), file_size(-1), ph_format(-1), ph_version(-1), uip(nullptr),
|
: 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) {
|
linker(nullptr), last_patch(nullptr), last_patch_len(0), last_patch_off(0) {
|
||||||
|
file_size = 0;
|
||||||
if (fi != nullptr)
|
if (fi != nullptr)
|
||||||
file_size = fi->st_size();
|
file_size = fi->st_size();
|
||||||
|
mem_size_assert(1, file_size_u);
|
||||||
uip = new UiPacker(this);
|
uip = new UiPacker(this);
|
||||||
mem_clear(&ph, sizeof(ph));
|
mem_clear(&ph, sizeof(ph));
|
||||||
}
|
}
|
||||||
@@ -504,7 +506,7 @@ void Packer::handleStub(InputFile *fif, OutputFile *fo, unsigned size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Packer::checkOverlay(unsigned overlay) {
|
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");
|
throw OverlayException("invalid overlay size; file is possibly corrupt");
|
||||||
if (overlay == 0)
|
if (overlay == 0)
|
||||||
return;
|
return;
|
||||||
@@ -515,7 +517,7 @@ void Packer::checkOverlay(unsigned overlay) {
|
|||||||
|
|
||||||
void Packer::copyOverlay(OutputFile *fo, unsigned overlay, MemBuffer *buf, bool do_seek) {
|
void Packer::copyOverlay(OutputFile *fo, unsigned overlay, MemBuffer *buf, bool do_seek) {
|
||||||
assert((int) overlay >= 0);
|
assert((int) overlay >= 0);
|
||||||
assert((off_t) overlay < file_size);
|
assert(overlay < file_size_u);
|
||||||
buf->checkState();
|
buf->checkState();
|
||||||
if (!fo || overlay == 0)
|
if (!fo || overlay == 0)
|
||||||
return;
|
return;
|
||||||
@@ -526,7 +528,7 @@ void Packer::copyOverlay(OutputFile *fo, unsigned overlay, MemBuffer *buf, bool
|
|||||||
}
|
}
|
||||||
info("Copying overlay: %d bytes", overlay);
|
info("Copying overlay: %d bytes", overlay);
|
||||||
if (do_seek)
|
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
|
// get buffer size, align to improve i/o speed
|
||||||
unsigned buf_size = buf->getSize();
|
unsigned buf_size = buf->getSize();
|
||||||
@@ -640,9 +642,9 @@ bool Packer::getPackHeader(void *b, int blen, bool allow_incompressible) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ph.c_len > ph.u_len || (ph.c_len == ph.u_len && !allow_incompressible) ||
|
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");
|
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
|
#if 0
|
||||||
// FIXME: does this check make sense w.r.t. overlays ???
|
// FIXME: does this check make sense w.r.t. overlays ???
|
||||||
if (ph.format == UPX_F_WIN32_PE || ph.format == UPX_F_DOS_EXE)
|
if (ph.format == UPX_F_WIN32_PE || ph.format == UPX_F_DOS_EXE)
|
||||||
|
|||||||
+7
-2
@@ -66,7 +66,7 @@ public:
|
|||||||
unsigned c_len;
|
unsigned c_len;
|
||||||
unsigned u_adler;
|
unsigned u_adler;
|
||||||
unsigned c_adler;
|
unsigned c_adler;
|
||||||
off_t u_file_size;
|
unsigned u_file_size;
|
||||||
int filter;
|
int filter;
|
||||||
int filter_cto;
|
int filter_cto;
|
||||||
int n_mru; // FIXME: rename to filter_misc
|
int n_mru; // FIXME: rename to filter_misc
|
||||||
@@ -291,7 +291,12 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
const N_BELE_RTP::AbstractPolicy *bele = nullptr; // target endianness
|
const N_BELE_RTP::AbstractPolicy *bele = nullptr; // target endianness
|
||||||
InputFile *fi = nullptr;
|
InputFile *fi = nullptr;
|
||||||
off_t file_size; // will get set by constructor
|
|
||||||
|
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()
|
PackHeader ph; // must be filled by canUnpack()
|
||||||
int ph_format;
|
int ph_format;
|
||||||
int ph_version;
|
int ph_version;
|
||||||
|
|||||||
+1
-1
@@ -2094,7 +2094,7 @@ void PeFile::readSectionHeaders(unsigned objs, unsigned sizeof_ih)
|
|||||||
}
|
}
|
||||||
mb_isection.alloc(sizeof(pe_section_t) * objs);
|
mb_isection.alloc(sizeof(pe_section_t) * objs);
|
||||||
isection = (pe_section_t *)mb_isection.getVoidPtr();
|
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);
|
char buf[32]; snprintf(buf, sizeof(buf), "too many sections %d", objs);
|
||||||
throwCantPack(buf);
|
throwCantPack(buf);
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-920
@@ -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"
|
#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) {
|
int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap) {
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
@@ -781,7 +14,10 @@ int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list a
|
|||||||
else
|
else
|
||||||
assert(max_size == 0);
|
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
|
// postconditions
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
@@ -809,14 +45,12 @@ int upx_vasprintf(char **ptr, const char *format, va_list ap) {
|
|||||||
|
|
||||||
assert(ptr != nullptr);
|
assert(ptr != nullptr);
|
||||||
*ptr = nullptr;
|
*ptr = nullptr;
|
||||||
#if defined(va_copy)
|
|
||||||
va_list ap_copy;
|
va_list ap_copy;
|
||||||
va_copy(ap_copy, ap);
|
va_copy(ap_copy, ap);
|
||||||
len = upx_vsnprintf(nullptr, 0, format, ap_copy);
|
len = upx_vsnprintf(nullptr, 0, format, ap_copy);
|
||||||
va_end(ap_copy);
|
va_end(ap_copy);
|
||||||
#else
|
|
||||||
len = upx_vsnprintf(nullptr, 0, format, ap);
|
|
||||||
#endif
|
|
||||||
if (len >= 0) {
|
if (len >= 0) {
|
||||||
*ptr = (char *) malloc(len + 1);
|
*ptr = (char *) malloc(len + 1);
|
||||||
assert(*ptr != nullptr);
|
assert(*ptr != nullptr);
|
||||||
@@ -846,152 +80,5 @@ upx_rsize_t upx_strlen(const char *s) {
|
|||||||
return len;
|
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: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+4
-10
@@ -566,11 +566,6 @@ void UiPacker::uiTestTotal() { uiFooter("Tested"); }
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool UiPacker::uiFileInfoStart() {
|
bool UiPacker::uiFileInfoStart() {
|
||||||
#if defined(_WIN32) // msvcrt
|
|
||||||
#define PRLLD "I64d"
|
|
||||||
#else
|
|
||||||
#define PRLLD "lld"
|
|
||||||
#endif
|
|
||||||
total_files++;
|
total_files++;
|
||||||
|
|
||||||
int fg = con_fg(stdout, FG_CYAN);
|
int fg = con_fg(stdout, FG_CYAN);
|
||||||
@@ -578,16 +573,15 @@ bool UiPacker::uiFileInfoStart() {
|
|||||||
fg = con_fg(stdout, fg);
|
fg = con_fg(stdout, fg);
|
||||||
UNUSED(fg);
|
UNUSED(fg);
|
||||||
if (p->ph.c_len > 0) {
|
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",
|
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);
|
p->ph.version, p->ph.method, p->ph.level, p->ph.filter, p->ph.filter_cto);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} 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");
|
con_fprintf(stdout, ", not compressed by UPX\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#undef PRLLD
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiPacker::uiFileInfoEnd() { uiUpdate(); }
|
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) {
|
void UiPacker::uiUpdate(upx_off_t fc_len, upx_off_t fu_len) {
|
||||||
update_fc_len = (fc_len >= 0) ? fc_len : p->file_size;
|
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_fu_len = (fu_len >= 0) ? fu_len : p->ph.u_file_size;
|
||||||
update_c_len = p->ph.c_len;
|
update_c_len = p->ph.c_len;
|
||||||
update_u_len = p->ph.u_len;
|
update_u_len = p->ph.u_len;
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ protected:
|
|||||||
virtual void doCallback(unsigned isize, unsigned osize);
|
virtual void doCallback(unsigned isize, unsigned osize);
|
||||||
|
|
||||||
protected:
|
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:
|
public:
|
||||||
static void uiHeader();
|
static void uiHeader();
|
||||||
|
|||||||
Reference in New Issue
Block a user