diff --git a/TODO b/TODO index 428d4e00..05a8e19c 100644 --- a/TODO +++ b/TODO @@ -13,6 +13,9 @@ UPX TODO list. Last updated 2002-07-16. - check all to make sure they are not invalid +- throwNotCompressible() is not a real error, so make the output nicer + (info: bla bla). Also ui.cpp (total_*). + TEST: diff --git a/src/.cvsignore b/src/.cvsignore index 40cf0dda..8913cfa6 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -1,3 +1,4 @@ +GNUmakefile *.0?? *.dat *.idb @@ -10,6 +11,7 @@ .gdbinit .Attic .deps +compress_nrv.* upx upx_nrv upx_nrv.* diff --git a/src/Makefile b/src/Makefile index 3865faff..2f7f44aa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,6 +24,8 @@ ifeq ($(strip $(UCLDIR)),) UCLDIR = $(HOME)/local/src/ucl-1.01 endif +##target = + DEBUG = 0 @@ -75,13 +77,12 @@ OBJECTS1 = \ packer$o packerf$o packhead$o packmast$o \ p_com$o p_djgpp2$o p_elks$o p_exe$o \ p_lx_elf$o p_lx_exc$o p_lx_sep$o p_lx_sh$o \ - p_psx$o \ - p_sys$o p_tmt$o p_tos$o \ + p_psx$o p_sys$o p_tmt$o p_tos$o \ p_unix$o p_vmlinz$o p_w16ne$o p_w32pe$o p_wcle$o # no exceptions or RTTI OBJECTS2 = \ - filteri$o help$o main$o mygetopt$o util$o \ + filteri$o help$o main$o mygetopt$o snprintf$o util$o \ c_init$o c_file$o c_none$o c_screen$o \ s_object$o s_djgpp2$o s_vcsa$o s_win32$o @@ -108,7 +109,7 @@ e = CC = gcc DEFS = INCLUDES = -INCLUDES = -I. -I$(srcdir) +##INCLUDES = -I. -I$(srcdir) CFLAGS_OUTPUT = -o $@ LINK_EXE = $(CXXLD) $(LDFLAGS) -o $@ $^ $(LDLIBS) @@ -168,14 +169,15 @@ UCLDIR:=$(strip $(subst \,/,$(UCLDIR))) NRVDIR:=$(strip $(subst \,/,$(NRVDIR))) u = ucl U = UCL -upx_exe = upx$e +upx_exe_tail = include $(srcdir)/Makefile.inc ifneq ($(strip $(wildcard $(NRVDIR)/include/nrv)),) u = nrv U = NRV - upx_exe = upx_$u$e + upx_exe_tail = _$(u) include $(srcdir)/Makefile.inc endif +upx_exe = upx$(upx_exe_tail)$(e) override tmp := -Wl,--rpath, LDRPATH := $(addprefix $(tmp),$(LIBDIRS)) @@ -279,6 +281,12 @@ CC = m68k-atari-mint-gcc CC += -m68040 endif +ifeq ($(target),cross-mint-m68020-60) +e = .ttp +CC = m68k-atari-mint-gcc +CC += -m68020-60 -m68881 +endif + ### ### djgpp2 @@ -290,8 +298,8 @@ CC += -march=i386 -mcpu=i586 ##CFLAGS_M += -mno-schedule-prologue CFLAGS_WERROR = -Werror STUBEDIT_EXE = stubedit $@ bufsize=0xfc00 -ifneq ($(strip $(wildcard $(DJDIR)/bin/mfxdjstubify.exe)),) -ifneq ($(strip $(wildcard $(DJDIR)/bin/cwsdstub.exe)),) +ifneq ($(strip $(wildcard $(DJDIR)/bin/mfxdjstubify.ex[eE])),) +ifneq ($(strip $(wildcard $(DJDIR)/bin/cwsdstub.ex[eE])),) STUBIFY_EXE = mfxdjstubify -v -s $(DJDIR)/bin/cwsdstub.exe $(upx_exe) endif endif @@ -481,9 +489,14 @@ endif # wcc # /*********************************************************************** -# // malloc debuggers and memory checkers +# // malloc debuggers and memory checkers - somewhat obsolete, use valgrind # ************************************************************************/ +ifeq (1,2) + # compile in extra valgrind support + CFLAGS += -DWITH_VALGRIND +endif + ifeq (1,2) LDLIBS += -lefence endif @@ -500,11 +513,6 @@ ifeq (1,2) ##LDFLAGS += -Wl,-defsym,_DYNAMIC=0 endif -ifeq (1,2) - CFLAGS += -DWITH_MSS - LDLIBS += -lmss -endif - # /*********************************************************************** # // finish settings @@ -550,7 +558,7 @@ CXXFLAGS2 = $(CXXFLAGS1) all: $(upx_exe) -.PHONY: all unupx mostlyclean clean distclean maintainer-clean untabify tags +.PHONY: all mostlyclean clean distclean maintainer-clean untabify tags $(upx_exe): $(OBJECTS) $(LIBS) $(RESOURCES) $(LINK_EXE) @@ -559,13 +567,6 @@ $(upx_exe): $(OBJECTS) $(LIBS) $(RESOURCES) $(CHMOD_EXE) -unupx: - $(MAKE) target=vc6 unupx.dll - -unupx.dll: $(OBJECTS) $(LIBS) - $(LINK_DLL) - - mostlyclean: -rm -f *.d *.err *.i *.log *.map *~ gdb-trans* diff --git a/src/bele.h b/src/bele.h index 4ca9de89..adb0062b 100644 --- a/src/bele.h +++ b/src/bele.h @@ -36,7 +36,7 @@ inline unsigned get_be16(const void *bb) { - const upx_bytep b = reinterpret_cast(bb); + const upx_bytep b = (const upx_bytep) bb; unsigned v; v = (unsigned) b[1] << 0; v |= (unsigned) b[0] << 8; @@ -45,7 +45,7 @@ inline unsigned get_be16(const void *bb) inline void set_be16(void *bb, unsigned v) { - upx_bytep b = reinterpret_cast(bb); + upx_bytep b = (upx_bytep) bb; b[1] = (unsigned char) (v >> 0); b[0] = (unsigned char) (v >> 8); } @@ -53,7 +53,7 @@ inline void set_be16(void *bb, unsigned v) inline unsigned get_be32(const void *bb) { - const upx_bytep b = reinterpret_cast(bb); + const upx_bytep b = (const upx_bytep) bb; unsigned v; v = (unsigned) b[3] << 0; v |= (unsigned) b[2] << 8; @@ -64,7 +64,7 @@ inline unsigned get_be32(const void *bb) inline void set_be32(void *bb, unsigned v) { - upx_bytep b = reinterpret_cast(bb); + upx_bytep b = (upx_bytep) bb; b[3] = (unsigned char) (v >> 0); b[2] = (unsigned char) (v >> 8); b[1] = (unsigned char) (v >> 16); @@ -74,23 +74,23 @@ inline void set_be32(void *bb, unsigned v) inline unsigned get_le16(const void *bb) { - const upx_bytep b = reinterpret_cast(bb); - unsigned v; #if defined(__i386__) - v = * (const unsigned short *) b; + return * (const unsigned short *) bb; #else + const upx_bytep b = (const upx_bytep) bb; + unsigned v; v = (unsigned) b[0] << 0; v |= (unsigned) b[1] << 8; -#endif return v; +#endif } inline void set_le16(void *bb, unsigned v) { - upx_bytep b = reinterpret_cast(bb); #if defined(__i386__) - (* (unsigned short *) b) = (unsigned short) v; + (* (unsigned short *) bb) = (unsigned short) (v & 0xffff); #else + upx_bytep b = (upx_bytep) bb; b[0] = (unsigned char) (v >> 0); b[1] = (unsigned char) (v >> 8); #endif @@ -99,7 +99,7 @@ inline void set_le16(void *bb, unsigned v) inline unsigned get_le24(const void *bb) { - const upx_bytep b = reinterpret_cast(bb); + const upx_bytep b = (const upx_bytep) bb; unsigned v; v = (unsigned) b[0] << 0; v |= (unsigned) b[1] << 8; @@ -109,7 +109,7 @@ inline unsigned get_le24(const void *bb) inline void set_le24(void *bb, unsigned v) { - upx_bytep b = reinterpret_cast(bb); + upx_bytep b = (upx_bytep) bb; b[0] = (unsigned char) (v >> 0); b[1] = (unsigned char) (v >> 8); b[2] = (unsigned char) (v >> 16); @@ -118,25 +118,25 @@ inline void set_le24(void *bb, unsigned v) inline unsigned get_le32(const void *bb) { - const upx_bytep b = reinterpret_cast(bb); - unsigned v; #if defined(__i386__) - v = * (const unsigned *) b; + return * (const unsigned *) bb; #else + const upx_bytep b = (const upx_bytep) bb; + unsigned v; v = (unsigned) b[0] << 0; v |= (unsigned) b[1] << 8; v |= (unsigned) b[2] << 16; v |= (unsigned) b[3] << 24; -#endif return v; +#endif } inline void set_le32(void *bb, unsigned v) { - upx_bytep b = reinterpret_cast(bb); #if defined(__i386__) - (* (unsigned *) b) = v; + (* (unsigned *) bb) = v; #else + upx_bytep b = (upx_bytep) bb; b[0] = (unsigned char) (v >> 0); b[1] = (unsigned char) (v >> 8); b[2] = (unsigned char) (v >> 16); @@ -318,6 +318,10 @@ int be16_compare(const void *e1, const void *e2); int be32_compare(const void *e1, const void *e2); int le16_compare(const void *e1, const void *e2); int le32_compare(const void *e1, const void *e2); +int be16_compare_signed(const void *e1, const void *e2); +int be32_compare_signed(const void *e1, const void *e2); +int le16_compare_signed(const void *e1, const void *e2); +int le32_compare_signed(const void *e1, const void *e2); // just for testing... diff --git a/src/c_init.cpp b/src/c_init.cpp index dcb44a66..9107709e 100644 --- a/src/c_init.cpp +++ b/src/c_init.cpp @@ -147,8 +147,8 @@ void con_fprintf(FILE *f, const char *format, ...) va_list args; char buf[80*25]; - va_start(args,format); - upx_vsnprintf(buf,sizeof(buf),format,args); + va_start(args, format); + upx_vsnprintf(buf, sizeof(buf), format,args); va_end(args); if (con == me) diff --git a/src/compress.ch b/src/compress.ch new file mode 100644 index 00000000..7c3c60ce --- /dev/null +++ b/src/compress.ch @@ -0,0 +1,242 @@ +/* compress.ch -- + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + */ + + +/************************************************************************* +// +**************************************************************************/ + +#if defined(upx_adler32) +unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) +{ + if (len == 0) + return adler; + assert(buf != NULL); + return ucl_adler32(adler, (const ucl_bytep)buf, len); +} +#endif + + +#if defined(upx_crc32) +unsigned upx_crc32(const void *buf, unsigned len, unsigned crc) +{ + if (len == 0) + return crc; + assert(buf != NULL); + return ucl_crc32(crc, (const ucl_bytep)buf, len); +} +#endif + + +/************************************************************************* +// +**************************************************************************/ + +#if defined(upx_compress) + +int upx_compress ( const upx_bytep src, upx_uint src_len, + upx_bytep dst, upx_uintp dst_len, + upx_progress_callback_t *cb, + int method, int level, + const struct upx_compress_config_t *conf_parm, + upx_uintp result ) +{ + struct upx_compress_config_t conf; + upx_uint result_buffer[16]; + int r = UPX_E_ERROR; + + assert(level > 0); + memset(&conf, 0xff, sizeof(conf)); + if (conf_parm) + conf = *conf_parm; // struct copy + if (!result) + result = result_buffer; + + // assume no info available - fill in worst case results + //result[0] = 1; // min_offset_found - NOT USED + result[1] = src_len - 1; // max_offset_found + //result[2] = 2; // min_match_found - NOT USED + result[3] = src_len - 1; // max_match_found + //result[4] = 1; // min_run_found - NOT USED + result[5] = src_len; // max_run_found + result[6] = 1; // first_offset_found + //result[7] = 999999; // same_match_offsets_found - NOT USED + + // prepare bit-buffer settings + conf.bb_endian = 0; + conf.bb_size = 0; + if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) + { + int n = (method - M_NRV2B_LE32) % 3; + if (n == 0) + conf.bb_size = 32; + else if (n == 1) + conf.bb_size = 8; + else + conf.bb_size = 16; + } + else + throwInternalError("unknown compression method"); + + // optimize compression parms + if (level <= 3 && conf.max_offset == UPX_UINT_MAX) + conf.max_offset = 8*1024-1; + else if (level == 4 && conf.max_offset == UPX_UINT_MAX) + conf.max_offset = 32*1024-1; + + if M_IS_NRV2B(method) + r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len, + cb, level, &conf, result); + else if M_IS_NRV2D(method) + r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len, + cb, level, &conf, result); +#if defined(ALG_NRV2E) + else if M_IS_NRV2E(method) + r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len, + cb, level, &conf, result); +#endif + else + throwInternalError("unknown compression method"); + + return r; +} + +#endif /* upx_compress */ + + +/************************************************************************* +// +**************************************************************************/ + +#if defined(upx_decompress) + +int upx_decompress ( const upx_bytep src, upx_uint src_len, + upx_bytep dst, upx_uintp dst_len, + int method ) +{ + int r = UPX_E_ERROR; + + switch (method) + { + case M_NRV2B_8: + r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2B_LE16: + r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2B_LE32: + r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2D_8: + r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2D_LE16: + r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2D_LE32: + r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL); + break; +#if defined(ALG_NRV2E) + case M_NRV2E_8: + r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2E_LE16: + r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL); + break; + case M_NRV2E_LE32: + r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL); + break; +#endif + default: + throwInternalError("unknown decompression method"); + break; + } + + return r; +} + +#endif /* upx_decompress */ + + +/************************************************************************* +// +**************************************************************************/ + +#if defined(upx_test_overlap) + +int upx_test_overlap ( const upx_bytep buf, upx_uint src_off, + upx_uint src_len, upx_uintp dst_len, + int method ) +{ + int r = UPX_E_ERROR; + + switch (method) + { + case M_NRV2B_8: + r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2B_LE16: + r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2B_LE32: + r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2D_8: + r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2D_LE16: + r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2D_LE32: + r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); + break; +#if defined(ALG_NRV2E) + case M_NRV2E_8: + r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2E_LE16: + r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); + break; + case M_NRV2E_LE32: + r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); + break; +#endif + default: + throwInternalError("unknown decompression method"); + break; + } + + return r; +} + +#endif /* upx_test_overlap */ + + +/* +vi:ts=4:et:nowrap +*/ + diff --git a/src/compress.cpp b/src/compress.cpp index 800163c0..2e288cb0 100644 --- a/src/compress.cpp +++ b/src/compress.cpp @@ -27,370 +27,23 @@ #include "conf.h" -#include "version.h" -#if 0 && defined(WITH_NRV) && defined(__i386__) -# define NRV_USE_ASM -#endif -#if 0 && defined(WITH_UCL) && defined(__i386__) -# define UCL_USE_ASM -#endif + #if defined(WITH_NRV) -# include -# include -//# include -# if !defined(NRV_VERSION) || (NRV_VERSION < 0x008000L) -# error -# endif - NRV_EXTERN_CDECL(int) nrv2b_99_compress_internal(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2d_99_compress_internal(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2e_99_compress_internal(const upx_byte *, ...); +# include "compress_nrv.ch" #elif defined(WITH_UCL) -# define nrv2b_99_compress_internal ucl_nrv2b_99_compress -# define nrv2d_99_compress_internal ucl_nrv2d_99_compress -# define nrv2e_99_compress_internal ucl_nrv2e_99_compress -#endif -#if 1 && defined(WITH_NRV) && defined(NRV_USE_ASM) -# if 1 && defined(NRV_USE_ASM) -# define nrv2b_decompress_safe_8 nrv2b_decompress_asm_safe_8 -# define nrv2b_decompress_safe_le16 nrv2b_decompress_asm_safe_le16 -# define nrv2b_decompress_safe_le32 nrv2b_decompress_asm_safe_le32 -# define nrv2d_decompress_safe_8 nrv2d_decompress_asm_safe_8 -# define nrv2d_decompress_safe_le16 nrv2d_decompress_asm_safe_le16 -# define nrv2d_decompress_safe_le32 nrv2d_decompress_asm_safe_le32 -# define nrv2e_decompress_safe_8 nrv2e_decompress_asm_safe_8 -# define nrv2e_decompress_safe_le16 nrv2e_decompress_asm_safe_le16 -# define nrv2e_decompress_safe_le32 nrv2e_decompress_asm_safe_le32 -# endif - NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_8(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_le16(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2b_decompress_safe_le32(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_8(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_le16(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2d_decompress_safe_le32(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_8(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_le16(const upx_byte *, ...); - NRV_EXTERN_CDECL(int) nrv2e_decompress_safe_le32(const upx_byte *, ...); -#elif defined(WITH_UCL) -# if defined(UCL_USE_ASM) -# include -# define nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8 -# define nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_asm_safe_le16 -# define nrv2b_decompress_safe_le32 ucl_nrv2b_decompress_asm_safe_le32 -# define nrv2d_decompress_safe_8 ucl_nrv2d_decompress_asm_safe_8 -# define nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_asm_safe_le16 -# define nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_asm_safe_le32 -# define nrv2e_decompress_safe_8 ucl_nrv2e_decompress_asm_safe_8 -# define nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_asm_safe_le16 -# define nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_asm_safe_le32 -# else -# define nrv2b_decompress_safe_8 ucl_nrv2b_decompress_safe_8 -# define nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_safe_le16 -# define nrv2b_decompress_safe_le32 ucl_nrv2b_decompress_safe_le32 -# define nrv2d_decompress_safe_8 ucl_nrv2d_decompress_safe_8 -# define nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_safe_le16 -# define nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_safe_le32 -# define nrv2e_decompress_safe_8 ucl_nrv2e_decompress_safe_8 -# define nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_safe_le16 -# define nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_safe_le32 +# define upx_adler32 upx_adler32 +//# define upx_crc32 upx_crc32 +# define upx_compress upx_compress +# define upx_decompress upx_decompress +# if (UPX_VERSION_HEX >= 0x019000) +# define upx_test_overlap upx_test_overlap # endif +# include "compress.ch" #else # error #endif -#if 0 && defined(WITH_ZLIB) && defined(M_ZLIB) -# include -#endif - - -/************************************************************************* -// -**************************************************************************/ - -unsigned upx_adler32(const void *buf, unsigned len, unsigned adler) -{ - if (len == 0) - return adler; - assert(buf != NULL); -#if defined(WITH_NRV) - return nrv_adler32(adler, (const nrv_byte *)buf, len); -#elif defined(WITH_UCL) - return ucl_adler32(adler, (const ucl_byte *)buf, len); -#endif -} - - -#if (UPX_VERSION_HEX >= 0x019000) -unsigned upx_adler32(unsigned adler, const void *buf, unsigned len) -{ - return upx_adler32(buf, len, adler); -} -#endif /* UPX_VERSION_HEX */ - - - -#if 0 // NOT USED -unsigned upx_crc32(const void *buf, unsigned len, unsigned crc) -{ - if (len == 0) - return crc; - assert(buf != NULL); -#if defined(WITH_NRV) - return nrv_crc32(crc, (const nrv_byte *)buf, len); -#elif defined(WITH_UCL) - return ucl_crc32(crc, (const ucl_byte *)buf, len); -#endif -} -#endif - - -/************************************************************************* -// -**************************************************************************/ - -int upx_compress ( const upx_byte *src, upx_uint src_len, - upx_byte *dst, upx_uint *dst_len, - upx_progress_callback_t *cb, - int method, int level, - const struct upx_compress_config_t *conf_parm, - upx_uintp result) -{ - struct upx_compress_config_t conf; - upx_uint result_buffer[16]; - int r = UPX_E_ERROR; - - assert(level > 0); - memset(&conf, 0xff, sizeof(conf)); - if (conf_parm) - conf = *conf_parm; // struct copy - if (!result) - result = result_buffer; - - // assume no info available - fill in worst case results - //result[0] = 1; // min_offset_found - NOT USED - result[1] = src_len - 1; // max_offset_found - //result[2] = 2; // min_match_found - NOT USED - result[3] = src_len - 1; // max_match_found - //result[4] = 1; // min_run_found - NOT USED - result[5] = src_len; // max_run_found - result[6] = 1; // first_offset_found - //result[7] = 999999; // same_match_offsets_found - NOT USED - -#if 0 && defined(WITH_ZLIB) && defined(M_ZLIB) - if (method == M_ZLIB) - { - uLong destLen = src_len + src_len / 8 + 256; - r = compress2(dst, &destLen, src, src_len, UPX_MIN(level, 9)); - *dst_len = destLen; - if (r == Z_MEM_ERROR) - return UPX_E_OUT_OF_MEMORY; - if (r != Z_OK) - return UPX_E_ERROR; - return UPX_E_OK; - } -#endif - - // prepare bit-buffer settings - conf.bb_endian = 0; - conf.bb_size = 0; - if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16) - { - int n = (method - M_NRV2B_LE32) % 3; - if (n == 0) - conf.bb_size = 32; - else if (n == 1) - conf.bb_size = 8; - else - conf.bb_size = 16; - } - else - throwInternalError("unknown compression method"); - -#if 1 && defined(WITH_NRV) - if (level == 1 && conf.bb_size == 32 && - conf.max_offset >= src_len && conf.max_match >= src_len) - { - if (method == M_NRV2B_LE32) - { - upx_byte wrkmem[NRV2B_1_16_MEM_COMPRESS]; -#if defined(__UPX_CHECKER) - memset(wrkmem,0,NRV2B_1_16_MEM_COMPRESS); -#endif - r = nrv2b_1_16_compress(src, src_len, dst, dst_len, wrkmem); - } - else if (method == M_NRV2D_LE32) - { - upx_byte wrkmem[NRV2D_1_16_MEM_COMPRESS]; -#if defined(__UPX_CHECKER) - memset(wrkmem,0,NRV2D_1_16_MEM_COMPRESS); -#endif - r = nrv2d_1_16_compress(src, src_len, dst, dst_len, wrkmem); - } -#if 0 - else if (method == M_NRV2E_LE32) - { - upx_byte wrkmem[NRV2E_1_16_MEM_COMPRESS]; -#if defined(__UPX_CHECKER) - memset(wrkmem,0,NRV2E_1_16_MEM_COMPRESS); -#endif - r = nrv2e_1_16_compress(src, src_len, dst, dst_len, wrkmem); - } -#endif - else - throwInternalError("unknown compression method"); - return r; - } -#endif - - // optimize compression parms - if (level <= 3 && conf.max_offset == UPX_UINT_MAX) - conf.max_offset = 8*1024-1; - else if (level == 4 && conf.max_offset == UPX_UINT_MAX) - conf.max_offset = 32*1024-1; -#if defined(WITH_NRV) - else if (level <= 6 && conf.max_offset == UPX_UINT_MAX) - conf.max_offset = 1*1024*1024-1; - else if (level <= 8 && conf.max_offset == UPX_UINT_MAX) - conf.max_offset = 2*1024*1024-1; - else if (level <= 10 && conf.max_offset == UPX_UINT_MAX) - conf.max_offset = 4*1024*1024-1; -#endif - - if M_IS_NRV2B(method) - r = nrv2b_99_compress_internal(src, src_len, dst, dst_len, - cb, level, &conf, result); - else if M_IS_NRV2D(method) - r = nrv2d_99_compress_internal(src, src_len, dst, dst_len, - cb, level, &conf, result); -#if 0 - else if M_IS_NRV2E(method) - r = nrv2e_99_compress_internal(src, src_len, dst, dst_len, - cb, level, &conf, result); -#endif - else - throwInternalError("unknown compression method"); - - return r; -} - - -/************************************************************************* -// -**************************************************************************/ - -int upx_decompress ( const upx_byte *src, upx_uint src_len, - upx_byte *dst, upx_uint *dst_len, - int method ) -{ - int r = UPX_E_ERROR; - -#if 0 && defined(WITH_ZLIB) && defined(M_ZLIB) - if (method == M_ZLIB) - { - uLong destLen = *dst_len; - r = uncompress(dst, &destLen, src, src_len); - *dst_len = destLen; - if (r == Z_MEM_ERROR) - return UPX_E_OUT_OF_MEMORY; - if (r != Z_OK) - return UPX_E_ERROR; - return UPX_E_OK; - } -#endif - - switch (method) - { - case M_NRV2B_8: - r = nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL); - break; - case M_NRV2B_LE16: - r = nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL); - break; - case M_NRV2B_LE32: - r = nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL); - break; - case M_NRV2D_8: - r = nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL); - break; - case M_NRV2D_LE16: - r = nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL); - break; - case M_NRV2D_LE32: - r = nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL); - break; -#if 0 - case M_NRV2E_8: - r = nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL); - break; - case M_NRV2E_LE16: - r = nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL); - break; - case M_NRV2E_LE32: - r = nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL); - break; -#endif - default: - throwInternalError("unknown decompression method"); - break; - } - - return r; -} - - -/************************************************************************* -// -**************************************************************************/ - -#if (UPX_VERSION_HEX >= 0x019000) - -int upx_test_overlap ( const upx_byte *buf, upx_uint src_off, - upx_uint src_len, upx_uint *dst_len, - int method ) -{ - int r = UPX_E_ERROR; - - switch (method) - { - case M_NRV2B_8: - r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL); - break; - case M_NRV2B_LE16: - r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); - break; - case M_NRV2B_LE32: - r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); - break; - case M_NRV2D_8: - r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL); - break; - case M_NRV2D_LE16: - r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); - break; - case M_NRV2D_LE32: - r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); - break; -#if 0 - case M_NRV2E_8: - r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL); - break; - case M_NRV2E_LE16: - r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL); - break; - case M_NRV2E_LE32: - r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL); - break; -#endif - default: - throwInternalError("unknown decompression method"); - break; - } - - return r; -} - -#endif /* UPX_VERSION_HEX */ - /* vi:ts=4:et:nowrap diff --git a/src/conf.h b/src/conf.h index f3036806..4eb219fa 100644 --- a/src/conf.h +++ b/src/conf.h @@ -36,10 +36,39 @@ #if defined(UPX_CONFIG_H) # include UPX_CONFIG_H #endif -#include +#if defined(HAVE_STDINT_H) +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# include +#endif +#include +#include "version.h" #include "tailor.h" +// upx_int64l is int_least64_t in terminology +#if !defined(upx_int64l) +# if defined(HAVE_STDINT_H) +# define upx_int64l int_least64_t +# define upx_uint64l uint_least64_t +# elif (ULONG_MAX > 0xffffffffL) +# define upx_int64l long int +# define upx_uint64l unsigned long int +# elif defined(__GNUC__) || defined(__DMC__) +# define upx_int64l long long int +# define upx_uint64l unsigned long long int +# elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__WATCOMC__) +# define upx_int64l __int64 +# define upx_uint64l unsigned __int64 +# else +# error "need a 64-bit integer type" +# endif +#endif + #if !defined(__i386__) # if defined(__386__) || defined(_M_IX86) # define __i386__ 1 @@ -58,25 +87,8 @@ #undef unix -#if defined(WITH_NRV) -# include -# if !defined(UPX_UINT_MAX) -# define UPX_UINT_MAX NRV_UINT_MAX -# define upx_uint nrv_uint -# define upx_voidp nrv_voidp -# define upx_uintp nrv_uintp -# define upx_byte nrv_byte -# define upx_bytep nrv_bytep -# define upx_bool nrv_bool -# define upx_progress_callback_t nrv_progress_callback_t -# define UPX_E_OK NRV_E_OK -# define UPX_E_ERROR NRV_E_ERROR -# define UPX_E_OUT_OF_MEMORY NRV_E_OUT_OF_MEMORY -# define __UPX_ENTRY __NRV_ENTRY -# endif -# if 1 && defined(__i386__) && !defined(__BORLANDC__) && !defined(__DMC__) -# define NRV_USE_ASM -# endif +#if !defined(WITH_UCL) +# error "you lose" #endif #if defined(WITH_UCL) # include @@ -92,6 +104,7 @@ # define upx_byte ucl_byte # define upx_bytep ucl_bytep # define upx_bool ucl_bool +# define upx_compress_config_t ucl_compress_config_t # define upx_progress_callback_t ucl_progress_callback_t # define UPX_E_OK UCL_E_OK # define UPX_E_ERROR UCL_E_ERROR @@ -99,21 +112,17 @@ # define __UPX_ENTRY __UCL_ENTRY # endif #endif +#if defined(WITH_NRV) +# include +#endif #if !defined(__UPX_CHECKER) # if defined(__UCL_CHECKER) || defined(__NRV_CHECKER) # define __UPX_CHECKER # endif #endif -#if !defined(UPX_UINT_MAX) || (UINT_MAX < 0xffffffffL) +#if !defined(UINT_MAX) || (UINT_MAX < 0xffffffffL) # error "you lose" #endif -#if !defined(WITH_UCL) -# error "you lose" -#endif - -#ifndef WITH_ZLIB -# define WITH_ZLIB 1 -#endif /************************************************************************* @@ -177,7 +186,9 @@ // malloc debuggers -#if defined(WITH_DMALLOC) +#if defined(WITH_VALGRIND) +# include +#elif defined(WITH_DMALLOC) # define DMALLOC_FUNC_CHECK # include #elif defined(WITH_GC) @@ -189,9 +200,20 @@ # define malloc GC_MALLOC # define realloc GC_REALLOC # define free GC_FREE -#elif defined(WITH_MSS) -# define MSS -# include +#endif + +#if !defined(VALGRIND_MAKE_WRITABLE) +# define VALGRIND_MAKE_WRITABLE(addr,len) 0 +#endif +#if !defined(VALGRIND_MAKE_READABLE) +# if 0 +# define VALGRIND_MAKE_READABLE(addr,len) memset(addr,0,len), 0 +# else +# define VALGRIND_MAKE_READABLE(addr,len) 0 +# endif +#endif +#if !defined(VALGRIND_DISCARD) +# define VALGRIND_DISCARD(handle) ((void) &handle) #endif @@ -210,10 +232,6 @@ (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) #endif -#if defined(NO_BOOL) -typedef int bool; -enum { false, true }; -#endif #if !defined(PATH_MAX) # define PATH_MAX 512 @@ -231,6 +249,7 @@ enum { false, true }; #endif typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int); + #undef MODE_T #if defined(HAVE_MODE_T) # define MODE_T mode_t @@ -238,6 +257,7 @@ typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int); # define MODE_T int #endif + #if !defined(HAVE_STRCASECMP) # if defined(HAVE_STRICMP) # define strcasecmp stricmp @@ -341,10 +361,11 @@ typedef RETSIGTYPE (SIGTYPEENTRY *sig_type)(int); #endif +#undef NOTHROW #if defined(__cplusplus) -#define NOTHROW throw() +# define NOTHROW throw() #else -#define NOTHROW +# define NOTHROW #endif @@ -436,17 +457,10 @@ inline void operator delete[](void *p) // gets destructed when leaving scope or on exceptions. // "var" is declared as a read-only reference to a pointer // and behaves exactly like an array "var[]". -#if 0 -# define Array(type, var, size) \ +#define Array(type, var, size) \ assert((int)(size) > 0); \ - std::vector var ## _array_vec((size)); \ - type * const & var = & var ## _array_vec[0] -#else -# define Array(type, var, size) \ - assert((int)(size) > 0); \ - MemBuffer var ## _array_buf((size)*(sizeof(type))); \ - type * const & var = ((type *) var ## _array_buf.getVoidPtr()) -#endif + MemBuffer var ## _membuf((size)*(sizeof(type))); \ + type * const & var = ((type *) var ## _membuf.getVoidPtr()) #define ByteArray(var, size) Array(unsigned char, var, size) @@ -516,111 +530,17 @@ inline void operator delete[](void *p) // globals **************************************************************************/ -// options - command -enum { - CMD_NONE, - CMD_COMPRESS, CMD_DECOMPRESS, CMD_TEST, CMD_LIST, CMD_FILEINFO, - CMD_HELP, CMD_LICENSE, CMD_VERSION -}; - +#include "snprintf.h" #if defined(__cplusplus) #include "stdcxx.h" +#include "options.h" #include "except.h" #include "bele.h" #include "util.h" #include "console.h" -struct options_t { - int cmd; - - // compression options - int method; - int level; // compression level 1..10 - int filter; // preferred filter from Packer::getFilters() - bool all_methods; // try all available compression methods ? - bool all_filters; // try all available filters ? - - // other options - int backup; - int console; - int debug; - int force; - int info_mode; - bool ignorewarn; - bool no_env; - bool no_progress; - const char *output_name; - int small; - int verbose; - bool to_stdout; - - // overlay handling - enum { - SKIP_OVERLAY = 0, - COPY_OVERLAY = 1, - STRIP_OVERLAY = 2 - }; - int overlay; - - // compression runtime parameters - see struct ucl_compress_config_t - struct { - upx_uint max_offset; - upx_uint max_match; - int s_level; - int h_level; - int p_level; - int c_flags; - upx_uint m_size; - } crp; - - // CPU - enum { - CPU_DEFAULT = 0, - CPU_8086 = 1, - CPU_286 = 2, - CPU_386 = 3, - CPU_486 = 4, - CPU_586 = 5, - CPU_686 = 6 - }; - int cpu; - - // options for various executable formats - struct { - bool force_stub; - bool no_reloc; - } dos; - struct { - bool coff; - } djgpp2; - struct { - unsigned no_align; - } psx; - struct { - bool split_segments; - } tos; - struct { - unsigned blocksize; - bool force_execve; // force the linux/386 execve format - enum { SCRIPT_MAX = 32 }; - const char *script_name; - } unix; - struct { - bool le; - } wcle; - struct { - int compress_exports; - int compress_icons; - int compress_resources; - signed char compress_rt[25]; // 25 == RT_LAST - int strip_relocs; - } w32pe; -}; - -extern struct options_t * volatile opt; - // main.cpp extern const char *progname; @@ -679,40 +599,22 @@ void show_version(int); // compress.cpp unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1); -unsigned upx_adler32(unsigned adler, const void *buf, unsigned len); +unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0); -#if defined(WITH_NRV) -struct nrv_compress_config_t; -struct nrv_compress_config_t -{ - int bb_endian; - int bb_size; - nrv_uint max_offset; - nrv_uint max_match; - int s_level; - int h_level; - int p_level; - int c_flags; - nrv_uint m_size; -}; -#define upx_compress_config_t nrv_compress_config_t -#elif defined(WITH_UCL) -#define upx_compress_config_t ucl_compress_config_t -#endif - -int upx_compress ( const upx_byte *src, upx_uint src_len, - upx_byte *dst, upx_uint *dst_len, +int upx_compress ( const upx_bytep src, upx_uint src_len, + upx_bytep dst, upx_uintp dst_len, upx_progress_callback_t *cb, int method, int level, const struct upx_compress_config_t *conf, - upx_uintp result); -int upx_decompress ( const upx_byte *src, upx_uint src_len, - upx_byte *dst, upx_uint *dst_len, + upx_uintp result ); +int upx_decompress ( const upx_bytep src, upx_uint src_len, + upx_bytep dst, upx_uintp dst_len, int method ); -int upx_test_overlap ( const upx_byte *buf, upx_uint src_off, - upx_uint src_len, upx_uint *dst_len, +int upx_test_overlap ( const upx_bytep buf, upx_uint src_off, + upx_uint src_len, upx_uintp dst_len, int method ); + #endif /* __cplusplus */ diff --git a/src/config_h/linux.h b/src/config_h/linux.h index 354b2059..54d042b1 100644 --- a/src/config_h/linux.h +++ b/src/config_h/linux.h @@ -29,12 +29,6 @@ /* Define to `long' if doesn't define. */ /* #undef ptrdiff_t */ -/* The number of bytes in a ptrdiff_t. */ -#define SIZEOF_PTRDIFF_T 4 - -/* The number of bytes in a size_t. */ -#define SIZEOF_SIZE_T 4 - /* Define when using the dmalloc package. */ /* #undef WITH_DMALLOC */ @@ -179,6 +173,9 @@ /* Define if you have the header file. */ #define HAVE_STDDEF_H 1 +/* Define if you have the header file. */ +#define HAVE_STDINT_H 1 + /* Define if you have the header file. */ #define HAVE_SYS_PARAM_H 1 @@ -225,14 +222,6 @@ # undef /**/ HAVE_SYS_TIMES_H #endif -#if (SIZEOF_PTRDIFF_T <= 0) -# undef /**/ SIZEOF_PTRDIFF_T -#endif - -#if (SIZEOF_SIZE_T <= 0) -# undef /**/ SIZEOF_SIZE_T -#endif - #endif /* already included */ /* diff --git a/src/config_h/sparc_sun_solaris28.h b/src/config_h/sparc_sun_solaris28.h new file mode 100644 index 00000000..67225ff2 --- /dev/null +++ b/src/config_h/sparc_sun_solaris28.h @@ -0,0 +1,226 @@ +/* pseudo for sparc-sun-solaris2.8 */ + +#ifndef __UPX_CONFIG_H +#define __UPX_CONFIG_H + +/* $TOP$ */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if your memcmp is broken. */ +/* #undef NO_MEMCMP */ + +/* Define to `long' if doesn't define. */ +/* #undef ptrdiff_t */ + +/* Define when using the dmalloc package. */ +/* #undef WITH_DMALLOC */ + +/* Define if you have the access function. */ +#define HAVE_ACCESS 1 + +/* Define if you have the atoi function. */ +#define HAVE_ATOI 1 + +/* Define if you have the chmod function. */ +#define HAVE_CHMOD 1 + +/* Define if you have the chown function. */ +#define HAVE_CHOWN 1 + +/* Define if you have the ctime function. */ +#define HAVE_CTIME 1 + +/* Define if you have the difftime function. */ +#define HAVE_DIFFTIME 1 + +/* Define if you have the fchmod function. */ +#define HAVE_FCHMOD 1 + +/* Define if you have the fileno function. */ +#define HAVE_FILENO 1 + +/* Define if you have the fstat function. */ +#define HAVE_FSTAT 1 + +/* Define if you have the XXX function. */ +#define HAVE_GETPID 1 + +/* Define if you have the XXX function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the getumask function. */ +/* #undef HAVE_GETUMASK */ + +/* Define if you have the gmtime function. */ +#define HAVE_GMTIME 1 + +/* Define if you have the index function. */ +#define HAVE_INDEX 1 + +/* Define if you have the isatty function. */ +#define HAVE_ISATTY 1 + +/* Define if you have the lstat function. */ +#define HAVE_LSTAT 1 + +/* Define if you have the localtime function. */ +#define HAVE_LOCALTIME 1 + +/* Define if you have the memcmp function. */ +#define HAVE_MEMCMP 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the memset function. */ +#define HAVE_MEMSET 1 + +/* Define if you have the mktime function. */ +#define HAVE_MKTIME 1 + +/* Define if you have the setmode function. */ +/* #undef HAVE_SETMODE */ + +/* Define if you have the stat function. */ +#define HAVE_STAT 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have the stricmp function. */ +/* #undef HAVE_STRICMP */ + +/* Define if you have the strncasecmp function. */ +#define HAVE_STRNCASECMP 1 + +/* Define if you have the strnicmp function. */ +/* #undef HAVE_STRNICMP */ + +/* Define if you have the strstr function. */ +#define HAVE_STRSTR 1 + +/* Define if you have the tzset function. */ +#define HAVE_TZSET 1 + +/* Define if you have the umask function. */ +#define HAVE_UMASK 1 + +/* Define if you have the utime function. */ +#define HAVE_UTIME 1 + +/* Define if you have the vsnprintf function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define if you have the header file. */ +#define HAVE_CTYPE_H 1 + +/* Define if you have the header file. */ +#define HAVE_CURSES_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_KD_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_KDEV_T_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_MAJOR_H 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +#define HAVE_NCURSES_H 1 + +/* Define if you have the header file. */ +#define HAVE_SIGNAL_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIMES_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_UTIME_H */ + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* $BOTTOM$ */ + +#if defined(HAVE_GMTIME) && !defined(TIME_WITH_SYS_TIME) +# undef /**/ HAVE_GMTIME +#endif + +#if defined(HAVE_LOCALTIME) && !defined(TIME_WITH_SYS_TIME) +# undef /**/ HAVE_LOCALTIME +#endif + +#if defined(HAVE_STRFTIME) && !defined(TIME_WITH_SYS_TIME) +# undef /**/ HAVE_STRFTIME +#endif + +#if defined(HAVE_SYS_RESOURCE_H) && !defined(TIME_WITH_SYS_TIME) +# undef /**/ HAVE_SYS_RESOURCE_H +#endif + +#if defined(HAVE_SYS_TIMES_H) && !defined(TIME_WITH_SYS_TIME) +# undef /**/ HAVE_SYS_TIMES_H +#endif + +#endif /* already included */ + +/* +vi:ts=4 +*/ diff --git a/src/file.h b/src/file.h index 8a442354..891023c4 100644 --- a/src/file.h +++ b/src/file.h @@ -120,6 +120,7 @@ public: off_t getBytesWritten() const { return bytes_written; } +#if (UPX_VERSION_HEX >= 0x019000) // FIXME - these won't work when using the `--stdout' option virtual void seek(off_t off, int whence) { @@ -132,6 +133,7 @@ public: write(buf, len); bytes_written -= len; // restore } +#endif // util static void dump(const char *name, const void *buf, int len, int flags=-1); diff --git a/src/filter/sub16.h b/src/filter/sub16.h index 75db923d..9add845a 100644 --- a/src/filter/sub16.h +++ b/src/filter/sub16.h @@ -31,7 +31,7 @@ // **************************************************************************/ -#include "filter/sub.hh" +#include "sub.hh" #define SUB16(f, N) SUB(f, N, unsigned short, get_le16, set_le16) #define ADD16(f, N) ADD(f, N, unsigned short, get_le16, set_le16) diff --git a/src/filter/sub32.h b/src/filter/sub32.h index 3643e436..7cdd19ef 100644 --- a/src/filter/sub32.h +++ b/src/filter/sub32.h @@ -31,7 +31,7 @@ // **************************************************************************/ -#include "filter/sub.hh" +#include "sub.hh" #define SUB32(f, N) SUB(f, N, unsigned int, get_le32, set_le32) #define ADD32(f, N) ADD(f, N, unsigned int, get_le32, set_le32) diff --git a/src/filter/sub8.h b/src/filter/sub8.h index f4669850..c97ffbf3 100644 --- a/src/filter/sub8.h +++ b/src/filter/sub8.h @@ -31,7 +31,7 @@ // **************************************************************************/ -#include "filter/sub.hh" +#include "sub.hh" #define SUB8(f, N) SUB(f, N, unsigned char, get_8, set_8) #define ADD8(f, N) ADD(f, N, unsigned char, get_8, set_8) diff --git a/src/help.cpp b/src/help.cpp index a8b69695..49287ccd 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,13 +21,12 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ #include "conf.h" -#include "version.h" /************************************************************************* diff --git a/src/main.cpp b/src/main.cpp index 37202858..12a5bb6f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,13 +21,12 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ #include "conf.h" -#include "version.h" #include "mygetopt.h" #include "file.h" #include "packer.h" @@ -505,6 +504,10 @@ static int do_option(int optc, const char *arg) if (!set_method(M_NRV2D_LE32, -1)) e_method(M_NRV2D_LE32, opt->level); break; + case 705: + if (!set_method(M_NRV2E_LE32, -1)) + e_method(M_NRV2E_LE32, opt->level); + break; // compression level case '1': @@ -766,12 +769,9 @@ static const struct mfx_option longopts[] = {"color", 0, 0, 514}, // compression method - {"2b", 0x10, 0, 702}, // --2b - {"n2b", 0x10, 0, 702}, // --n2b {"nrv2b", 0x10, 0, 702}, // --nrv2b - {"2d", 0x10, 0, 704}, // --2d - {"n2d", 0x10, 0, 704}, // --n2d {"nrv2d", 0x10, 0, 704}, // --nrv2d + {"nrv2e", 0x10, 0, 705}, // --nrv2e // compression settings {"all-filters", 0x10, 0, 523}, {"all-methods", 0x10, 0, 524}, @@ -1002,6 +1002,10 @@ void upx_sanity_check(void) COMPILE_TIME_ASSERT(sizeof(void *) >= 4); COMPILE_TIME_ASSERT(sizeof(long) >= sizeof(void *)); + COMPILE_TIME_ASSERT(sizeof(upx_int64l) >= 8); + COMPILE_TIME_ASSERT(sizeof(upx_int64l) >= sizeof(long)); + COMPILE_TIME_ASSERT(sizeof(upx_int64l) == sizeof(upx_uint64l)); + COMPILE_TIME_ASSERT(sizeof(off_t) >= sizeof(long)); COMPILE_TIME_ASSERT(((off_t) -1) < 0); COMPILE_TIME_ASSERT(sizeof(ptrdiff_t) >= sizeof(int)); @@ -1112,10 +1116,6 @@ int main(int argc, char *argv[]) upx_sanity_check(); init_options(opt); -#if defined(WITH_MSS) - MSS_DISABLE_LOG_OUTPUT; -#endif - if (!argv[0] || !argv[0][0]) argv[0] = default_argv0; argv0 = argv[0]; diff --git a/src/options.h b/src/options.h new file mode 100644 index 00000000..fb523d8e --- /dev/null +++ b/src/options.h @@ -0,0 +1,141 @@ +/* options.h -- + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + */ + + +#ifndef __UPX_OPTIONS_H +#define __UPX_OPTIONS_H + + +/************************************************************************* +// globals +**************************************************************************/ + +// options - command +enum { + CMD_NONE, + CMD_COMPRESS, CMD_DECOMPRESS, CMD_TEST, CMD_LIST, CMD_FILEINFO, + CMD_HELP, CMD_LICENSE, CMD_VERSION +}; + + +struct options_t { + int cmd; + + // compression options + int method; + int level; // compression level 1..10 + int filter; // preferred filter from Packer::getFilters() + bool all_methods; // try all available compression methods ? + bool all_filters; // try all available filters ? + + // other options + int backup; + int console; + int debug; + int force; + int info_mode; + bool ignorewarn; + bool no_env; + bool no_progress; + const char *output_name; + int small; + int verbose; + bool to_stdout; + + // overlay handling + enum { + SKIP_OVERLAY = 0, + COPY_OVERLAY = 1, + STRIP_OVERLAY = 2 + }; + int overlay; + + // compression runtime parameters - see struct ucl_compress_config_t + struct { + upx_uint max_offset; + upx_uint max_match; + int s_level; + int h_level; + int p_level; + int c_flags; + upx_uint m_size; + } crp; + + // CPU + enum { + CPU_DEFAULT = 0, + CPU_8086 = 1, + CPU_286 = 2, + CPU_386 = 3, + CPU_486 = 4, + CPU_586 = 5, + CPU_686 = 6 + }; + int cpu; + + // options for various executable formats + struct { + bool force_stub; + bool no_reloc; + } dos; + struct { + bool coff; + } djgpp2; + struct { + bool no_align; + } psx; + struct { + bool split_segments; + } tos; + struct { + unsigned blocksize; + bool force_execve; // force the linux/386 execve format + enum { SCRIPT_MAX = 32 }; + const char *script_name; + } unix; + struct { + bool le; + } wcle; + struct { + int compress_exports; + int compress_icons; + int compress_resources; + signed char compress_rt[25]; // 25 == RT_LAST + int strip_relocs; + } w32pe; +}; + +extern struct options_t * volatile opt; + + +#endif /* already included */ + + +/* +vi:ts=4:et +*/ + diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 60fe2742..c0b50aac 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -164,7 +164,7 @@ void PackLinuxI386elf::packExtent( // compressWithFilters() updates u_adler _inside_ compress(); // that is, AFTER filtering. We want BEFORE filtering, // so that decompression checks the end-to-end checksum. - end_u_adler = upx_adler32(ph.u_adler, ibuf, ph.u_len); + end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler); ft->buf_len = l; compressWithFilters(ft, OVERHEAD, strategy); } @@ -181,7 +181,7 @@ void PackLinuxI386elf::packExtent( else { ph. c_len = ph.u_len; // must update checksum of compressed data - ph.c_adler = upx_adler32(ph.c_adler, ibuf, ph.u_len); + ph.c_adler = upx_adler32(ibuf, ph.u_len, ph.c_adler); } // write block sizes @@ -338,7 +338,7 @@ void PackLinuxI386elf::unpackExtent(unsigned wanted, OutputFile *fo, int j = blocksize + OVERHEAD - sz_cpr; fi->readx(ibuf+j, sz_cpr); // update checksum of compressed data - c_adler = upx_adler32(c_adler, ibuf + j, sz_cpr); + c_adler = upx_adler32(ibuf + j, sz_cpr, c_adler); // decompress if (sz_cpr < sz_unc) { @@ -355,7 +355,7 @@ void PackLinuxI386elf::unpackExtent(unsigned wanted, OutputFile *fo, j = 0; } // update checksum of uncompressed data - u_adler = upx_adler32(u_adler, ibuf + j, sz_unc); + u_adler = upx_adler32(ibuf + j, sz_unc, u_adler); total_in += sz_cpr; total_out += sz_unc; // write block diff --git a/src/p_lx_sep.cpp b/src/p_lx_sep.cpp index bc3e97d1..3a905e83 100644 --- a/src/p_lx_sep.cpp +++ b/src/p_lx_sep.cpp @@ -54,7 +54,7 @@ const upx_byte *PackLinuxI386sep::getLoader() const if (0==name) { name = "/usr/local/lib/upxX"; } - sprintf(script, "#!%s\n", name); + upx_snprintf(script, sizeof(script), "#!%s\n", name); if (M_IS_NRV2B(ph.method)) { script[strlen(script)-2] = 'b'; return (upx_byte const *)script; diff --git a/src/p_psx.cpp b/src/p_psx.cpp index c3f0adde..baa176a0 100644 --- a/src/p_psx.cpp +++ b/src/p_psx.cpp @@ -30,7 +30,6 @@ #include "filter.h" #include "packer.h" #include "p_psx.h" -#include "version.h" static const #include "stub/l_psx.h" diff --git a/src/p_tos.cpp b/src/p_tos.cpp index 92579cb5..680a2794 100644 --- a/src/p_tos.cpp +++ b/src/p_tos.cpp @@ -640,7 +640,7 @@ int PackTos::canUnpack() { if (!readFileHeader()) return false; - if (!readPackHeader(512)) + if (!readPackHeader(768)) return false; // check header as set by packer if ((ih.fh_text & 3) != 0 || (ih.fh_data & 3) != 0 || (ih.fh_bss & 3) != 0 diff --git a/src/p_unix.cpp b/src/p_unix.cpp index 7bf4bd11..460120c7 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -158,7 +158,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft) // compressWithFilters() updates u_adler _inside_ compress(); // that is, AFTER filtering. We want BEFORE filtering, // so that decompression checks the end-to-end checksum. - unsigned const end_u_adler = upx_adler32(ph.u_adler, ibuf, ph.u_len); + unsigned const end_u_adler = upx_adler32(ibuf, ph.u_len, ph.u_adler); compressWithFilters(&ft, OVERHEAD, strategy); if (ph.c_len < ph.u_len) { @@ -170,7 +170,7 @@ void PackUnix::pack2(OutputFile *fo, Filter &ft) // block is not compressible ph.c_len = ph.u_len; // must manually update checksum of compressed data - ph.c_adler = upx_adler32(ph.c_adler, ibuf, ph.u_len); + ph.c_adler = upx_adler32(ibuf, ph.u_len, ph.c_adler); } // write block header @@ -370,7 +370,7 @@ void PackUnix::unpack(OutputFile *fo) i = blocksize + OVERHEAD - sz_cpr; fi->readx(buf+i, sz_cpr); // update checksum of compressed data - c_adler = upx_adler32(c_adler, buf + i, sz_cpr); + c_adler = upx_adler32(buf + i, sz_cpr, c_adler); // decompress if (sz_cpr < sz_unc) { decompress(buf+i, buf, false); @@ -383,7 +383,7 @@ void PackUnix::unpack(OutputFile *fo) i = 0; } // update checksum of uncompressed data - u_adler = upx_adler32(u_adler, buf + i, sz_unc); + u_adler = upx_adler32(buf + i, sz_unc, u_adler); total_in += sz_cpr; total_out += sz_unc; // write block diff --git a/src/p_wcle.cpp b/src/p_wcle.cpp index 108b120b..e3336f40 100644 --- a/src/p_wcle.cpp +++ b/src/p_wcle.cpp @@ -2,8 +2,8 @@ This file is part of the UPX executable compressor. - Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996-2001 Laszlo Molnar + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar All Rights Reserved. UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - Markus F.X.J. Oberhumer Laszlo Molnar - markus@oberhumer.com ml1050@cdata.tvnet.hu + Markus F.X.J. Oberhumer Laszlo Molnar + */ @@ -283,7 +283,7 @@ void PackWcle::preprocessFixups() for (ic = jc = 0; ic < objects; ic++) jc += counts[ic]; - ByteArray(rl,jc); + ByteArray(rl, jc); ByteArray(srf, counts[objects+0]+1); ByteArray(slf, counts[objects+1]+1); @@ -296,7 +296,7 @@ void PackWcle::preprocessFixups() { while ((unsigned)(fix - ifixups) < get_le32(ifpage_table+ic+1)) { - const signed short fixp2 = (signed short) get_le16(fix+2); + const int fixp2 = get_le16_signed(fix+2); unsigned value; switch (*fix) @@ -318,7 +318,7 @@ void PackWcle::preprocessFixups() fix += 5; break; case 5: // 16-bit offset - if ((unsigned short)fixp2 < 4096 && IOT(fix[4]-1,my_base_address) == jc) + if ((unsigned)fixp2 < 4096 && IOT(fix[4]-1,my_base_address) == jc) dputc('6',stdout); else throwCantPack("unsupported 16-bit offset relocation"); @@ -461,7 +461,8 @@ void PackWcle::pack(OutputFile *fo) readImage(); readNonResidentNames(); - if (find_le32(iimage,20,get_le32("UPX ")) >= 0) +// if (find_le32(iimage,20,get_le32("UPX ")) >= 0) + if (find_le32(iimage,UPX_MIN(soimage,256u),UPX_MAGIC_LE32) >= 0) throwAlreadyPacked(); if (ih.init_ss_object != objects) @@ -546,7 +547,7 @@ void PackWcle::pack(OutputFile *fo) // copy the overlay const unsigned overlaystart = ih.data_pages_offset + exe_offset - + mps * (pages - 1) + ih.bytes_on_last_page; + + getImageSize(); const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length; checkOverlay(overlay); copyOverlay(fo, overlay, &oimage); @@ -762,7 +763,9 @@ int PackWcle::canUnpack() return false; fi->seek(exe_offset + ih.data_pages_offset, SEEK_SET); // FIXME: 1024 could be too large for some files - return readPackHeader(1024) ? 1 : -1; + //int len = 1024; + int len = UPX_MIN(getImageSize(), 256u); + return readPackHeader(len) ? 1 : -1; } diff --git a/src/packer.cpp b/src/packer.cpp index 72606a63..6114385f 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -28,7 +28,6 @@ //#define WANT_STL #include "conf.h" -#include "version.h" #include "file.h" #include "packer.h" #include "filter.h" @@ -157,7 +156,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out, ph.saved_u_adler = ph.u_adler; ph.saved_c_adler = ph.c_adler; // update checksum of uncompressed data - ph.u_adler = upx_adler32(ph.u_adler,in,ph.u_len); + ph.u_adler = upx_adler32(in, ph.u_len, ph.u_adler); // set compression paramters upx_compress_config_t conf; @@ -231,7 +230,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out, return false; // update checksum of compressed data - ph.c_adler = upx_adler32(ph.c_adler,out,ph.c_len); + ph.c_adler = upx_adler32(out, ph.c_len, ph.c_adler); // Decompress and verify. Skip this when using the fastest level. if (ph.level > 1) { @@ -245,7 +244,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out, throwInternalError("decompression failed (size error)"); // verify decompression - if (ph.u_adler != upx_adler32(ph.saved_u_adler,in,ph.u_len)) + if (ph.u_adler != upx_adler32(in, ph.u_len, ph.saved_u_adler)) throwInternalError("decompression failed (checksum error)"); } return true; @@ -303,7 +302,7 @@ void Packer::decompress(const upx_bytep in, upx_bytep out, // verify checksum of compressed data if (verify_checksum) { - adler = upx_adler32(ph.saved_c_adler, in, ph.c_len); + adler = upx_adler32(in, ph.c_len, ph.saved_c_adler); if (adler != ph.c_adler) throwChecksumError(); } @@ -317,7 +316,7 @@ void Packer::decompress(const upx_bytep in, upx_bytep out, // verify checksum of decompressed data if (verify_checksum) { - adler = upx_adler32(ph.saved_u_adler, out, ph.u_len); + adler = upx_adler32(out, ph.u_len, ph.saved_u_adler); if (adler != ph.u_adler) throwChecksumError(); } @@ -927,18 +926,19 @@ char const *Packer::identstr(unsigned &size) static const char identbig[] = "\n\0" "$Info: " - "This file is packed with the UPX executable packer http://upx.tsx.org $" + "This file is packed with the UPX executable packer http://upx.sf.net $" "\n\0" "$Id: UPX " UPX_VERSION_STRING4 - " Copyright (C) 1996-2001 the UPX Team. All Rights Reserved. $" + " Copyright (C) 1996-2002 the UPX Team. All Rights Reserved. $" "\n"; - static const char identsmall[] = "\n" "$Id: UPX " - "(C) 1996-2001 the UPX Team. All Rights Reserved. http://upx.tsx.org $" + "(C) 1996-2002 the UPX Team. All Rights Reserved. http://upx.sf.net $" "\n"; +// static const char identtiny[] = UPX_VERSION_STRING4; +// FIXME if (opt->small) { size = sizeof(identsmall); diff --git a/src/packer.h b/src/packer.h index 6c23bc37..2f883dcd 100644 --- a/src/packer.h +++ b/src/packer.h @@ -112,7 +112,7 @@ public: virtual ~Packer(); virtual int getVersion() const = 0; - // A unique integer ID for this executable format. See unupx.h. + // A unique integer ID for this executable format. See conf.h. virtual int getFormat() const = 0; virtual const char *getName() const = 0; virtual const int *getCompressionMethods(int method, int level) const = 0; diff --git a/src/s_djgpp2.cpp b/src/s_djgpp2.cpp index 94d06a39..68cc9cfd 100644 --- a/src/s_djgpp2.cpp +++ b/src/s_djgpp2.cpp @@ -123,7 +123,7 @@ static __inline__ unsigned short make_cell(screen_t *this, int ch, int attr) { UNUSED(this); - return ((attr & 0xff) << 8) | (ch & 0xff); + return (unsigned short) (((attr & 0xff) << 8) | (ch & 0xff)); } diff --git a/src/s_vcsa.cpp b/src/s_vcsa.cpp index 7ec73b9e..3bcfeec7 100644 --- a/src/s_vcsa.cpp +++ b/src/s_vcsa.cpp @@ -331,11 +331,11 @@ static int init(screen_t *this, int fd) int attr; unsigned short a; - sprintf(vc_name, "/dev/vcsa%d", (int) MINOR(st.st_rdev)); + upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcsa%d", (int) MINOR(st.st_rdev)); this->data->fd = open(vc_name, O_RDWR); if (this->data->fd == -1) { - sprintf(vc_name, "/dev/vcc/a%d", (int) MINOR(st.st_rdev)); + upx_snprintf(vc_name, sizeof(vc_name), "/dev/vcc/a%d", (int) MINOR(st.st_rdev)); this->data->fd = open(vc_name, O_RDWR); } if (this->data->fd != -1) diff --git a/src/s_win32.cpp b/src/s_win32.cpp index 133e5948..58071ecf 100644 --- a/src/s_win32.cpp +++ b/src/s_win32.cpp @@ -188,6 +188,7 @@ static void putCharAttr(screen_t *this, int ch, int attr, int x, int y) { CHAR_INFO ci; SMALL_RECT region = { P(x), P(y), P(x), P(y) }; + ci.Char.UnicodeChar = 0; ci.Char.AsciiChar = (CHAR) ch; ci.Attributes = (WORD) attr; WriteConsoleOutputA(this->data->ho, &ci, size11, pos00, ®ion); @@ -213,6 +214,7 @@ static void putStringAttr(screen_t *this, const char *s, int attr, int x, int y) SMALL_RECT region = { P(x), P(y), P(x + l - 1), P(y) }; for (i = 0; i < l; i++) { + ci[i].Char.UnicodeChar = 0; ci[i].Char.AsciiChar = *s++; ci[i].Attributes = (WORD) attr; } @@ -355,6 +357,7 @@ static void updateLineN(screen_t *this, const void *line, int y, int len) SMALL_RECT region = { 0, P(y), P(0 + l - 1), P(y) }; for (i = 0; i < l; i++) { + ci[i].Char.UnicodeChar = 0; ci[i].Char.AsciiChar = *s++; ci[i].Attributes = *s++; } diff --git a/src/snprintf.cpp b/src/snprintf.cpp new file mode 100644 index 00000000..785724fb --- /dev/null +++ b/src/snprintf.cpp @@ -0,0 +1,997 @@ +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell (papowell@astart.com) + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions + */ + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * Andrew Tridgell (tridge@samba.org) Oct 1998 + * fixed handling of %.0f + * added test for HAVE_LONG_DOUBLE + * + * tridge@samba.org, idra@samba.org, April 2001 + * got rid of fcvt code (twas buggy and made testing harder) + * added C99 semantics + * + * markus@oberhumer.com, August 2002 + * large modifications for use in UPX + * + **************************************************************/ + + +#if 1 +#include "conf.h" +#else +#include +#include +#include +#include +#undef NDEBUG +#include +#endif + +#undef LLONG +#undef ULLONG +#if 1 && defined(upx_int64l) +# define LLONG upx_int64l +# define ULLONG upx_uint64l +#else +# define LLONG long int +# define ULLONG unsigned long int +#endif + +#undef NO_FLOAT +#undef LDOUBLE +#if 1 +# define NO_FLOAT +# define float error_no_float +# define double error_no_float +#elif 0 || defined(HAVE_LONG_DOUBLE) +# define LDOUBLE long double +#else +# define LDOUBLE double +#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) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LLONG 4 + +#define char_to_int(p) ((p)- '0') +#undef MAX +#define MAX(p,q) (((p) >= (q)) ? (p) : (q)) + + +/************************************************************************* + // +**************************************************************************/ + +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, int c) +{ + if (*currlen < maxlen) + buffer[*currlen] = (char) c; + *currlen += 1; +} + + +static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, + const char *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + +#ifdef DEBUG_SNPRINTF + printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); +#endif + if (value == NULL) + value = ""; + + for (strln = 0; value[strln]; ) /* strlen */ + ++strln; + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + ++cnt; + } +} + + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ +static void fmtint(char *buffer, size_t *currlen, size_t maxlen, + LLONG value, unsigned base, 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, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + /* Zeros */ + while (zpadlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + /* Digits */ + while (place > 0) + dopr_outch (buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } +} + + +/************************************************************************* +// floating format support +**************************************************************************/ + +#if !defined(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 *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) +{ + /* avoid warnings with `gcc -Wshadow' */ +#undef index +#define index iindex + 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, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch (buffer, currlen, maxlen, 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, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + } + + while (zpadlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } +#undef index +} + + +#endif /* !defined(NO_FLOAT) */ + + +/************************************************************************* +// dopr() +**************************************************************************/ + +static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args) +{ + char ch; + LLONG value; +#if !defined(NO_FLOAT) + LDOUBLE fvalue; +#endif + const char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; + ch = *format++; + + while (state != DP_S_DONE) { + if (ch == '\0') + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch (buffer, &currlen, maxlen, 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; + } + 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; + } + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { /* It's a long long */ + cflags = DP_C_LLONG; + 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_SHORT) + value = va_arg (args, int); + else if (cflags == DP_C_LONG) + value = va_arg (args, long int); + else if (cflags == DP_C_LLONG) + value = va_arg (args, LLONG); + else + value = va_arg (args, int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (long)va_arg (args, ULLONG); + else + value = (long)va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (LLONG)va_arg (args, ULLONG); + else + value = (long)va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned int); + else if (cflags == DP_C_LONG) + value = (long)va_arg (args, unsigned long int); + else if (cflags == DP_C_LLONG) + value = (LLONG)va_arg (args, ULLONG); + else + value = (long)va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + break; +#if !defined(NO_FLOAT) + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + /* um, floating point? */ + fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + 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; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + break; +#else + case 'f': + case 'E': + case 'e': + case 'G': + case 'g': + assert(0); + exit(255); +#endif /* !defined(NO_FLOAT) */ + case 'c': + dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); + break; + case 's': + strvalue = va_arg (args, char *); + if (!strvalue) strvalue = "(NULL)"; + if (max == -1) { + max = strlen(strvalue); + } + if (min > 0 && max >= 0 && min > max) max = min; + fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = (const char *) va_arg (args, void *); + fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg (args, short int *); + *num = (short int)currlen; + } else if (cflags == DP_C_LONG) { + long int *num; + num = va_arg (args, long int *); + *num = (long int)currlen; + } else if (cflags == DP_C_LLONG) { + LLONG *num; + num = va_arg (args, LLONG *); + *num = (LLONG)currlen; + } else { + int *num; + num = va_arg (args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch (buffer, &currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + 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 */ + } + } + if (maxlen != 0) { + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else + buffer[maxlen - 1] = '\0'; + } + + return currlen; +} + + +/************************************************************************* +// public entries +**************************************************************************/ + +// UPX version with assertions +static int xdopr(char *buffer, size_t maxlen, const char *format, va_list args) +{ + size_t ret; + + // preconditions + if (buffer != NULL) + assert((int)maxlen > 0); + else + assert(maxlen == 0); + + ret = dopr(buffer, maxlen, format, args); + + // postconditions + if (buffer != NULL) + { + assert((int)ret >= 0); + assert(ret < maxlen); + assert(buffer[ret] == '\0'); + } + + return (int) ret; +} + + +int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap) +{ + return xdopr(str, count, format, ap); +} + + +int upx_snprintf(char *str, size_t count, const char *format,...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = xdopr(str, count, format, ap); + va_end(ap); + return ret; +} + + +int upx_vasprintf(char **ptr, const char *format, va_list ap) +{ + int ret; + + assert(ptr != NULL); + *ptr = NULL; + ret = xdopr(NULL, 0, format, ap); + if (ret > 0) + { + *ptr = (char *) malloc(ret + 1); + assert(*ptr != NULL); + if (*ptr == NULL) + return -1; + ret = xdopr(*ptr, ret+1, format, ap); + } + return ret; +} + + +int upx_asprintf(char **ptr, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = upx_vasprintf(ptr, format, ap); + va_end(ap); + return ret; +} + + +/************************************************************************* + // +**************************************************************************/ + +#if 0 || defined(TEST_SNPRINTF) + +#undef sprintf +#include +#include +#include + +#undef snprintf +#define snprintf upx_snprintf +//int sprintf(char *str,const char *fmt,...); + +int main(void) +{ + char buf1[1024]; + char buf2[1024]; + const char *fp_fmt[] = { + "%1.1f", + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + "%.0f", + "%f", + "-16.16f", + NULL + }; + 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", + NULL + }; + const long 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", NULL}; + 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(NULL, 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(NULL, 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 */ + +/* +vi:ts=4:et +*/ + diff --git a/src/snprintf.h b/src/snprintf.h new file mode 100644 index 00000000..32c9b883 --- /dev/null +++ b/src/snprintf.h @@ -0,0 +1,62 @@ +/* snprintf.h -- + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2002 Laszlo Molnar + All Rights Reserved. + + UPX and the UCL library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Markus F.X.J. Oberhumer Laszlo Molnar + + */ + + +#ifndef __UPX_SNPRINTF_H +#define __UPX_SNPRINTF_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************* +// +**************************************************************************/ + +int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap); +int upx_snprintf(char *str, size_t count, const char *format,...); +int upx_vasprintf(char **ptr, const char *format, va_list ap); +int upx_asprintf(char **ptr, const char *format, ...); + +#if 1 +# undef sprintf +# define sprintf error_sprintf_is_dangerous_use_snprintf +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* already included */ + + +/* +vi:ts=4:et:nowrap +*/ + diff --git a/src/stub/Makefile b/src/stub/Makefile index 340c8601..d7a1481f 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -2,7 +2,7 @@ # UPX stub Makefile (GNU make) # # see http://upx.sourceforge.net/download/tools/ -# for required support tools +# for required build tools # ifeq ($(strip $(UCLDIR)),) @@ -76,13 +76,13 @@ NASM = /usr/topics/asm/nasm-20000903/nasm -O2 -w+macro-params -w+orphan-labe NASM = nasm -w+macro-params -w+orphan-labels NASM += -i$(srcdir)/ -APP = perl -w $(srcdir)/scripts/app.pl +APP_I386 = perl -w $(srcdir)/scripts/app_i386.pl BIN2H = perl -w $(srcdir)/scripts/bin2h.pl BRANDELF = perl -w $(srcdir)/scripts/brandelf.pl O2BIN = perl -w $(srcdir)/scripts/o2bin.pl ##SETFOLD = /bin/sh $(srcdir)/scripts/setfold.sh ##STRIPELF = perl -w $(srcdir)/scripts/stripelf.pl -STRIPELF = ./util/sstrip/sstrip +STRIPELF = $(srcdir)/util/sstrip/sstrip # Use gcc 2.95.2 for smallest code. CC_LINUX_CFLAGS = -Wall -W -Wcast-align -Wcast-qual -Wwrite-strings @@ -98,18 +98,18 @@ ifeq (1,1) # Preprocessor for the a68k 68000-assembler. CPP_M68K = gcc -I$(UCL_UPX) -E -x assembler-with-cpp -Wall -Wp,-P,-C,-traditional -D__A68K__ ##CPP_M68K = cpp -I$(UCL_UPX) -x assembler-with-cpp -P -C -traditional -nostdinc -D__A68K__ -APP_M68K = perl -w $(srcdir)/scripts/app_68k.pl +APP_M68K = perl -w $(srcdir)/scripts/app_m68k.pl ASM_M68K = a68k -q -x else # Preprocessor for the asl 68000-assembler. CPP_M68K = gcc -I$(UCL_UPX) -E -x assembler-with-cpp -Wall -Wp,-P,-C,-traditional -D__ASL__ -APP_M68K = perl -w $(srcdir)/scripts/app_68k.pl -ASM_M68K = sh $(srcdir)/scripts/asl_68k.sh +APP_M68K = perl -w $(srcdir)/scripts/app_m68k.pl +ASM_M68K = sh $(srcdir)/scripts/asl_m68k.sh endif # MIPS R3000 -APP_R3K = perl -w $(srcdir)/scripts/app_r3k.pl -ASM_R3K = asm5900 --nologo -q +APP_MR3K = perl -w $(srcdir)/scripts/app_mr3k.pl +ASM_MR3K = asm5900 --nologo -q # /*********************************************************************** @@ -119,7 +119,7 @@ ASM_R3K = asm5900 --nologo -q .PHONY: default all stubs mostlyclean clean distclean maintainer-clean ident strings default: - @echo "UPX info: type 'make all' if you have all the needed build tools." + @echo "UPX info: type 'make all' if you have all the required build tools." all: stubs ## upxb upxd @@ -150,10 +150,10 @@ strings: all # ************************************************************************/ .asm.asx: - $(APP) $< $@ + $(APP_I386) $< $@ .ash.asy: - $(APP) $< $@ + $(APP_I386) $< $@ stubify.h: stub.asm @@ -296,7 +296,7 @@ fold_elf86.o: fold_elf86.asm fold_elf86.h: l_lx_elf.o fold_elf86.o l_lx_elf86.lds ld -T $(srcdir)/l_lx_elf86.lds -Map $T.map -o $T.bin $T.o l_lx_elf.o objcopy -S -R .comment -R .note $T.bin - ./util/sstrip/sstrip $T.bin + $(STRIPELF) $T.bin $(BRANDELF) $T.bin $(BIN2H) $T.bin linux_i386elf_fold $@ @@ -309,7 +309,7 @@ fold_exec86.o: fold_exec86.asm fold_exec86.h: l_lx_exec.o fold_exec86.o l_lx_exec86.lds ld -T $(srcdir)/l_lx_exec86.lds -Map $T.map -o $T.bin $T.o l_lx_exec.o objcopy -S -R .comment -R .note $T.bin - ./util/sstrip/sstrip $T.bin + $(STRIPELF) $T.bin $(BRANDELF) $T.bin $(BIN2H) $T.bin linux_i386exec_fold $@ @@ -322,7 +322,7 @@ fold_sh86.o: fold_sh86.asm fold_sh86.h: l_lx_sh.o fold_sh86.o l_lx_sh86.lds ld -T $(srcdir)/l_lx_sh86.lds -Map $T.map -o $T.bin $T.o l_lx_sh.o objcopy -S -R .comment -R .note $T.bin - ./util/sstrip/sstrip $T.bin + $(STRIPELF) $T.bin $(BRANDELF) $T.bin $(BIN2H) $T.bin linux_i386sh_fold $@ @@ -349,8 +349,8 @@ upxd: l_lx_sep.o l_lx_sep86.asm # ************************************************************************/ l_psx.h: l_psx.asm - $(APP_R3K) $< $T.asx - $(ASM_R3K) $T.asx -I$(UCL_UPX) -o$T.bin -l$T.lst + $(APP_MR3K) $< $T.asx + $(ASM_MR3K) $T.asx -I$(UCL_UPX) -o$T.bin -l$T.lst $(BIN2H) $T.bin nrv_loader $@ @@ -364,19 +364,19 @@ DEPS2 = header.asy macros.asy $(STUBS): $(srcdir)/scripts/bin2h.pl l_com.h: n2b_d16.asy $(DEPS2) -l_djgpp2.h: n2b_d32.asy n2d_d32.asy $(DEPS2) -l_exe.h: n2b_d8e.asy n2d_d8e.asy $(DEPS2) +l_djgpp2.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2) +l_exe.h: n2b_d8e.asy n2d_d8e.asy n2e_d8e.asy $(DEPS2) l_sys.h: n2b_d16.asy $(DEPS2) -l_t_n2b.h: n2b_d.ash bits.ash $(DEPS1) -l_t_n2bs.h: n2b_d.ash bits.ash $(DEPS1) -l_t_n2d.h: n2d_d.ash bits.ash $(DEPS1) -l_t_n2ds.h: n2d_d.ash bits.ash $(DEPS1) -l_tmt.h: n2b_d32.asy n2d_d32.asy $(DEPS2) -l_ext2.h: n2b_d32.asy n2d_d32.asy $(DEPS2) -l_vmlinz.h: n2b_d32.asy n2d_d32.asy $(DEPS2) -l_vxd.h: n2b_d32.asy n2d_d32.asy $(DEPS2) -l_wcle.h: n2b_d32.asy n2d_d32.asy $(DEPS2) -l_w32pe.h: n2b_d32.asy n2d_d32.asy $(DEPS2) +l_t_n2b.h: n2b_d.ash bits.ash $(DEPS1) +l_t_n2bs.h: n2b_d.ash bits.ash $(DEPS1) +l_t_n2d.h: n2d_d.ash bits.ash $(DEPS1) +l_t_n2ds.h: n2d_d.ash bits.ash $(DEPS1) +l_t_n2e.h: n2e_d.ash bits.ash $(DEPS1) +l_t_n2es.h: n2e_d.ash bits.ash $(DEPS1) +l_tmt.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2) +l_vxd.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2) +l_wcle.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2) +l_w32pe.h: n2b_d32.asy n2d_d32.asy n2e_d32.asy $(DEPS2) l_lx_elf86.h: l_lx_elf86.asm macros.ash macros.asy l_lx_exec86.h: l_lx_exec86.asm macros.ash macros.asy diff --git a/src/stub/l_exe.asm b/src/stub/l_exe.asm index e5104a14..69f3fd27 100644 --- a/src/stub/l_exe.asm +++ b/src/stub/l_exe.asm @@ -2,8 +2,8 @@ ; ; This file is part of the UPX executable compressor. ; -; Copyright (C) 1996-2001 Markus Franz Xaver Johannes Oberhumer -; Copyright (C) 1996-2001 Laszlo Molnar +; Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer +; Copyright (C) 1996-2002 Laszlo Molnar ; All Rights Reserved. ; ; UPX and the UCL library are free software; you can redistribute them @@ -21,8 +21,8 @@ ; If not, write to the Free Software Foundation, Inc., ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; -; Markus F.X.J. Oberhumer Laszlo Molnar -; markus@oberhumer.com ml1050@cdata.tvnet.hu +; Markus F.X.J. Oberhumer Laszlo Molnar +; ; @@ -85,6 +85,7 @@ do_copy: %include "n2b_d8e.ash" %include "n2d_d8e.ash" +%include "n2e_d8e.ash" ; ============= ; ============= RELOCATION diff --git a/src/stub/scripts/app.pl b/src/stub/scripts/app_i386.pl similarity index 98% rename from src/stub/scripts/app.pl rename to src/stub/scripts/app_i386.pl index b2269ac4..e871ef48 100644 --- a/src/stub/scripts/app.pl +++ b/src/stub/scripts/app_i386.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl -w # -# app.pl -- assembly preprocessor for upx +# app_i386.pl -- assembly preprocessor for upx # # This file is part of the UPX executable compressor. # diff --git a/src/stub/scripts/app_68k.pl b/src/stub/scripts/app_m68k.pl similarity index 97% rename from src/stub/scripts/app_68k.pl rename to src/stub/scripts/app_m68k.pl index d832addc..eea838de 100644 --- a/src/stub/scripts/app_68k.pl +++ b/src/stub/scripts/app_m68k.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl -w # -# app_68k.pl -- assembly preprocessor for upx +# app_m68k.pl -- assembly preprocessor for upx # # This file is part of the UPX executable compressor. # @@ -28,7 +28,7 @@ # # -# usage: app_68k.pl infile outfile +# usage: app_m68k.pl infile outfile # $in = shift || die; diff --git a/src/stub/scripts/app_r3k.pl b/src/stub/scripts/app_mr3k.pl similarity index 96% rename from src/stub/scripts/app_r3k.pl rename to src/stub/scripts/app_mr3k.pl index fed50af3..39e3c529 100644 --- a/src/stub/scripts/app_r3k.pl +++ b/src/stub/scripts/app_mr3k.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl -w # -# app_r3k.pl -- assembly preprocessor for upx +# app_mr3k.pl -- assembly preprocessor for upx # # This file is part of the UPX executable compressor. # @@ -28,7 +28,7 @@ # # -# usage: app_r3k.pl infile outfile +# usage: app_mr3k.pl infile outfile # $in = shift || die; diff --git a/src/stub/scripts/asl_m68k.sh b/src/stub/scripts/asl_m68k.sh new file mode 100644 index 00000000..261b1910 --- /dev/null +++ b/src/stub/scripts/asl_m68k.sh @@ -0,0 +1,50 @@ +#! /bin/sh +# +# asl_m68k.sh -- +# +# This file is part of the UPX executable compressor. +# +# Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer +# Copyright (C) 1996-2002 Laszlo Molnar +# All Rights Reserved. +# +# UPX and the UCL library are free software; you can redistribute them +# and/or modify them under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. +# If not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# Markus F.X.J. Oberhumer Laszlo Molnar +# +# + +set -e + +# wrapper for the ASL cross-assembler (version 1.42bld9) +# http://john.ccac.rwth-aachen.de:8000/as/ +# http://john.ccac.rwth-aachen.de:8000/ftp/as/source/c_version/ + +file="$1" +test -f "$file" || exit 1 + +ofile=`echo "$file" | sed 's/\.[a-z]*$/.o/'` + +# convert ' to " in dc.x statements +perl -p -i -e ' + s,\x27,",g if m,^\s*dc\.,; +' "$file" + +echo asl -q -xC -U -cpu 68000 -o "$ofile" -L "$file" + asl -q -xC -U -cpu 68000 -o "$ofile" -L "$file" + +exit 0 + diff --git a/src/stub/scripts/bin2h.pl b/src/stub/scripts/bin2h.pl index 9f75351a..cd3ef29d 100644 --- a/src/stub/scripts/bin2h.pl +++ b/src/stub/scripts/bin2h.pl @@ -53,7 +53,7 @@ if (1 && $st[7] <= 0) { } if (1 && $st[7] > 64*1024) { print STDERR "$ifile: ERROR: file is too big (${st[7]} bytes)\n"; - if ($st[7] > 1024*1024) { + if ($ifile =~ /^fold/) { print STDERR " (please upgrade your binutils to 2.12.90.0.15 or better)\n"; } exit(1); diff --git a/src/ui.cpp b/src/ui.cpp index b73c665d..5ac17150 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -271,13 +271,15 @@ void UiPacker::startCallback(unsigned u_len, unsigned step, // set pass if (total_passes > 1) { + int buflen, l; do { s->pass_digits++; total_passes /= 10; } while (total_passes > 0); - int l = sprintf(&s->msg_buf[s->bar_pos], "%*d/%*d ", - s->pass_digits, s->pass, - s->pass_digits, s->total_passes); + buflen = sizeof(s->msg_buf) - s->bar_pos; + l = upx_snprintf(&s->msg_buf[s->bar_pos], buflen, "%*d/%*d ", + s->pass_digits, s->pass, + s->pass_digits, s->total_passes); if (l > 0 && s->bar_len - l > 10) { s->bar_len -= l; @@ -385,7 +387,7 @@ void __UPX_ENTRY UiPacker::callback(upx_uint isize, upx_uint osize, int state, v if (state != -1 && state != 3) return; if (user) { - UiPacker *uip = reinterpret_cast(user); + UiPacker *uip = (UiPacker *) user; uip->doCallback(isize, osize); } } @@ -440,9 +442,10 @@ void UiPacker::doCallback(unsigned isize, unsigned osize) if (osize > 0) ratio = get_ratio(isize, osize); - sprintf(m," %3d.%1d%% %c ", - ratio / 10000, (ratio % 10000) / 1000, - spinner[s->spin_counter & 3]); + int buflen = &s->msg_buf[sizeof(s->msg_buf)] - m; + upx_snprintf(m, buflen, " %3d.%1d%% %c ", + ratio / 10000, (ratio % 10000) / 1000, + spinner[s->spin_counter & 3]); assert((int)strlen(s->msg_buf) < 1 + 80); s->pos = pos; @@ -593,8 +596,9 @@ void UiPacker::uiListTotal(bool decompress) if (opt->verbose >= 1 && total_files >= 2) { char name[32]; - upx_snprintf(name,sizeof(name),"[ %ld file%s ]", total_files_done, total_files_done == 1 ? "" : "s"); - con_fprintf(stdout,"%s%s\n", + upx_snprintf(name, sizeof(name), "[ %ld file%s ]", + total_files_done, total_files_done == 1 ? "" : "s"); + con_fprintf(stdout, "%s%s\n", header_line2, mkline(total_fu_len, total_fc_len, total_u_len, total_c_len, diff --git a/src/upx.rc b/src/upx.rc index a4594492..3b37ad61 100644 --- a/src/upx.rc +++ b/src/upx.rc @@ -1,11 +1,18 @@ #include #include "version.h" -#define VERSION_MAJOR ((UPX_VERSION_HEX >> 16) & 0xff) -#define VERSION_MINOR ((UPX_VERSION_HEX >> 8) & 0xff) -#define VERSION_MICRO ((UPX_VERSION_HEX >> 0) & 0xff) +#define VERSION_MAJOR 1 +#define VERSION_MINOR 90 +#define VERSION_MICRO 0 #define VERSION_STRING UPX_VERSION_STRING +#define H(v,s) ((0x ## v) << (s)) +#define VERSION_HEX \ + (H(VERSION_MAJOR, 16) | H(VERSION_MINOR, 8) | H(VERSION_MICRO, 0)) +#if (VERSION_HEX != UPX_VERSION_HEX) +# error "version mismatch" +#endif + #if 0 #ifdef _WIN32 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL diff --git a/src/util.cpp b/src/util.cpp index 350129c5..3951f58b 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -63,6 +63,35 @@ int le32_compare(const void *e1, const void *e2) } +int be16_compare_signed(const void *e1, const void *e2) +{ + const int d1 = get_be16_signed(e1); + const int d2 = get_be16_signed(e2); + return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); +} + +int be32_compare_signed(const void *e1, const void *e2) +{ + const int d1 = get_be32_signed(e1); + const int d2 = get_be32_signed(e2); + return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); +} + +int le16_compare_signed(const void *e1, const void *e2) +{ + const int d1 = get_le16_signed(e1); + const int d2 = get_le16_signed(e2); + return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); +} + +int le32_compare_signed(const void *e1, const void *e2) +{ + const int d1 = get_le32_signed(e1); + const int d2 = get_le32_signed(e2); + return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0); +} + + /************************************************************************* // find util **************************************************************************/ @@ -144,74 +173,37 @@ upx_bytep pfind(const void *b, int blen, const void *what, int wlen) upx_bytep pfind_be16(const void *b, int blen, unsigned what) { unsigned char w[2]; - set_be16(w,what); - return pfind(b,blen,w,2); + set_be16(w, what); + return pfind(b, blen, w, 2); } upx_bytep pfind_be32(const void *b, int blen, unsigned what) { unsigned char w[4]; - set_be32(w,what); - return pfind(b,blen,w,4); + set_be32(w, what); + return pfind(b, blen, w, 4); } upx_bytep pfind_le16(const void *b, int blen, unsigned what) { unsigned char w[2]; - set_le16(w,what); - return pfind(b,blen,w,2); + set_le16(w, what); + return pfind(b, blen, w, 2); } upx_bytep pfind_le32(const void *b, int blen, unsigned what) { unsigned char w[4]; - set_le32(w,what); - return pfind(b,blen,w,4); + set_le32(w, what); + return pfind(b, blen, w, 4); } #endif /* UPX_VERSION_HEX */ -/************************************************************************* -// string util -**************************************************************************/ - -int upx_snprintf(char *str, long n, const char *format, ...) -{ - int r = -1; - if (n > 0) - { - va_list args; - va_start(args,format); - r = upx_vsnprintf(str,n,format,args); - va_end(args); - } - assert(r >= 0 && r < n); // UPX assertion - return r; -} - - -int upx_vsnprintf(char *str, long n, const char *format, va_list ap) -{ - int r = -1; - if (n > 0) - { -#if defined(HAVE_VSNPRINTF) - r = vsnprintf(str,(size_t)n,format,ap); -#else - r = vsprintf(str,format,ap); -#endif - // UPX extension: make sure the string is '\0' terminated in any case - str[n-1] = 0; - } - assert(r >= 0 && r < n); // UPX assertion - return r; -} - - /************************************************************************* // ctype util **************************************************************************/ @@ -345,20 +337,21 @@ bool fn_is_same_file(const char *n1, const char *n2) #if 0 // not used #if defined(HAVE_LOCALTIME) -void tm2str(char *s, const struct tm *tmp) +void tm2str(char *s, size_t size, const struct tm *tmp) { - sprintf(s,"%04d-%02d-%02d %02d:%02d:%02d", - (int) tmp->tm_year + 1900, (int) tmp->tm_mon + 1, - (int) tmp->tm_mday, - (int) tmp->tm_hour, (int) tmp->tm_min, (int) tmp->tm_sec); + upx_snprintf(s, size, "%04d-%02d-%02d %02d:%02d:%02d", + (int) tmp->tm_year + 1900, (int) tmp->tm_mon + 1, + (int) tmp->tm_mday, + (int) tmp->tm_hour, (int) tmp->tm_min, (int) tmp->tm_sec); } #endif -void time2str(char *s, const time_t *t) +void time2str(char *s, size_t size, const time_t *t) { + assert(size >= 18); #if defined(HAVE_LOCALTIME) - tm2str(s,localtime(t)); + tm2str(s, size, localtime(t)); #elif defined(HAVE_CTIME) const char *p = ctime(t); memset(s, ' ', 16); @@ -402,12 +395,13 @@ bool set_method_name(char *buf, size_t size, int method, int level) void center_string(char *buf, size_t size, const char *s) { - size_t l = strlen(s); - size_t len = size - 1; - assert(l < size); - memset(buf, ' ', len); - memcpy(buf+(len-l)/2, s, l); - buf[len] = 0; + size_t l1 = size - 1; + size_t l2 = strlen(s); + assert(size > 0); + assert(l2 < size); + memset(buf, ' ', l1); + memcpy(buf+(l1-l2)/2, s, l2); + buf[l1] = 0; } @@ -442,12 +436,15 @@ bool file_exists(const char *name) } -bool maketempname(char *ofilename, const char *ifilename, - const char *ext, bool force) +bool maketempname(char *ofilename, size_t size, + const char *ifilename, const char *ext, bool force) { char *ofext = NULL, *ofname; int ofile = -1; + if (size <= 0) + return false; + strcpy(ofilename, ifilename); for (ofname = fn_basename(ofilename); *ofname; ofname++) { @@ -460,11 +457,12 @@ bool maketempname(char *ofilename, const char *ifilename, while (ofile < 1000) { + assert(strlen(ofilename) < size); if (!file_exists(ofilename)) return true; if (!force) break; - sprintf(ofext, ".%03d", ++ofile); + upx_snprintf(ofext, 5, ".%03d", ++ofile); } ofilename[0] = 0; @@ -472,11 +470,15 @@ bool maketempname(char *ofilename, const char *ifilename, } -bool makebakname(char *ofilename, const char *ifilename, bool force) +bool makebakname(char *ofilename, size_t size, + const char *ifilename, bool force) { char *ofext = NULL, *ofname; int ofile = -1; + if (size <= 0) + return false; + strcpy(ofilename, ifilename); for (ofname = fn_basename(ofilename); *ofname; ofname++) { @@ -495,11 +497,12 @@ bool makebakname(char *ofilename, const char *ifilename, bool force) while (ofile < 1000) { + assert(strlen(ofilename) < size); if (!file_exists(ofilename)) return true; if (!force) break; - sprintf(ofext, ".%03d", ++ofile); + upx_snprintf(ofext, 5, ".%03d", ++ofile); } ofilename[0] = 0; @@ -532,21 +535,10 @@ bool isafile(int fd) unsigned get_ratio(unsigned u_len, unsigned c_len) { -#if (ULONG_MAX <= 0xffffffffL) -# if defined(__GNUC__) || defined(__DMC__) - const unsigned long long n = 1000000; -# elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__WATCOMC__) - const unsigned __int64 n = 1000000; -# else -# error "need a 64-bit integer type" -# endif -#else - const unsigned long n = 1000000; -#endif - COMPILE_TIME_ASSERT(sizeof(n) >= 8); + const unsigned n = 1000000; if (u_len <= 0) - return (unsigned) n; - return (unsigned) ((c_len * n) / u_len) + 5; + return n; + return (unsigned) ((c_len * (upx_uint64l)n) / u_len) + 5; } diff --git a/src/util.h b/src/util.h index 953bcc2a..a988b876 100644 --- a/src/util.h +++ b/src/util.h @@ -34,18 +34,16 @@ // misc. support functions **************************************************************************/ -int upx_snprintf(char *str, long n, const char *format, ...); -int upx_vsnprintf(char *str, long n, const char *format, va_list ap); - char *fn_basename(const char *name); int fn_strcmp(const char *n1, const char *n2); char *fn_strlwr(char *n); bool fn_has_ext(const char *name, const char *ext, bool ignore_case=true); bool file_exists(const char *name); -bool maketempname(char *ofilename, const char *ifilename, - const char *ext, bool force=true); -bool makebakname(char *ofilename, const char *ifilename, bool force=true); +bool maketempname(char *ofilename, size_t size, + const char *ifilename, const char *ext, bool force=true); +bool makebakname(char *ofilename, size_t size, + const char *ifilename, bool force=true); bool isafile(int fd); unsigned get_ratio(unsigned u_len, unsigned c_len); diff --git a/src/version.h b/src/version.h index 417c5037..b280e2af 100644 --- a/src/version.h +++ b/src/version.h @@ -1,4 +1,4 @@ #define UPX_VERSION_HEX 0x019001 /* 01.90.01 */ #define UPX_VERSION_STRING "1.90.1" #define UPX_VERSION_STRING4 "1.90" -#define UPX_VERSION_DATE "Jul 16th 2002" +#define UPX_VERSION_DATE "Sep 9th 2002" diff --git a/src/work.cpp b/src/work.cpp index 5adb47ff..2a9dc1ac 100644 --- a/src/work.cpp +++ b/src/work.cpp @@ -31,7 +31,6 @@ #include "packmast.h" #include "packer.h" #include "ui.h" -#include "version.h" #if defined(__DJGPP__) @@ -114,7 +113,7 @@ void do_one_file(const char *iname, char *oname) strcpy(tname,opt->output_name); else { - if (!maketempname(tname,iname,".upx")) + if (!maketempname(tname, sizeof(tname), iname, ".upx")) throwIOException("could not create a temporary file name"); } if (opt->force >= 2) @@ -201,7 +200,7 @@ void do_one_file(const char *iname, char *oname) { // make backup char bakname[PATH_MAX+1]; - if (!makebakname(bakname,iname)) + if (!makebakname(bakname, sizeof(bakname), iname)) throwIOException("could not create a backup file name"); File::rename(iname,bakname); } @@ -264,10 +263,6 @@ void do_files(int i, int argc, char *argv[]) for ( ; i < argc; i++) { -#if defined(WITH_MSS) - //MSS_ENABLE_LOG_OUTPUT; - //MSS_ENTER_SCOPE; -#endif infoHeader(); const char *iname = argv[i]; @@ -308,11 +303,6 @@ void do_files(int i, int argc, char *argv[]) printUnhandledException(iname,NULL); e_exit(EXIT_ERROR); } - -#if defined(WITH_MSS) - //MSS_LEAVE_SCOPE; - MSS_CHECK_ALL_BLOCKS; -#endif } if (opt->cmd == CMD_COMPRESS)