mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
Some refactoring. NFC.
This commit is contained in:
parent
fab0c3b09d
commit
b0207ce524
|
@ -631,7 +631,7 @@ struct upx_compress_result_t
|
|||
// globals
|
||||
**************************************************************************/
|
||||
|
||||
#include "snprintf.h"
|
||||
#include "snprintf.h" // must get included first!
|
||||
#include "stdcxx.h"
|
||||
#include "options.h"
|
||||
#include "except.h"
|
||||
|
|
59
src/mem.cpp
59
src/mem.cpp
|
@ -30,65 +30,6 @@
|
|||
#include "mem.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// assert sane memory buffer sizes to protect against integer overflows
|
||||
// and malicious header fields
|
||||
**************************************************************************/
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_MEM == UPX_RSIZE_MAX)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_STR <= UPX_RSIZE_MAX / 256)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(2ull * UPX_RSIZE_MAX * 9 / 8 + 16*1024*1024 < INT_MAX)
|
||||
|
||||
upx_rsize_t mem_size(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1, upx_uint64_t extra2)
|
||||
{
|
||||
assert(element_size > 0);
|
||||
if (element_size > UPX_RSIZE_MAX) throwCantPack("mem_size 1; take care");
|
||||
if (n > UPX_RSIZE_MAX) throwCantPack("mem_size 2; take care");
|
||||
if (extra1 > UPX_RSIZE_MAX) throwCantPack("mem_size 3; take care");
|
||||
if (extra2 > UPX_RSIZE_MAX) throwCantPack("mem_size 4; take care");
|
||||
upx_uint64_t bytes = element_size * n + extra1 + extra2; // cannot overflow
|
||||
if (bytes > UPX_RSIZE_MAX) throwCantPack("mem_size 5; take care");
|
||||
return ACC_ICONV(upx_rsize_t, bytes);
|
||||
}
|
||||
|
||||
upx_rsize_t mem_size_get_n(upx_uint64_t element_size, upx_uint64_t n)
|
||||
{
|
||||
mem_size_assert(element_size, n);
|
||||
return ACC_ICONV(upx_rsize_t, n); // return n
|
||||
}
|
||||
|
||||
bool mem_size_valid(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1, upx_uint64_t extra2)
|
||||
{
|
||||
assert(element_size > 0);
|
||||
if (element_size > UPX_RSIZE_MAX) return false;
|
||||
if (n > UPX_RSIZE_MAX) return false;
|
||||
if (extra1 > UPX_RSIZE_MAX) return false;
|
||||
if (extra2 > UPX_RSIZE_MAX) return false;
|
||||
upx_uint64_t bytes = element_size * n + extra1 + extra2; // cannot overflow
|
||||
if (bytes > UPX_RSIZE_MAX) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mem_size_valid_bytes(upx_uint64_t bytes)
|
||||
{
|
||||
if (bytes > UPX_RSIZE_MAX) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int ptr_diff(const void *p1, const void *p2)
|
||||
{
|
||||
assert(p1 != NULL);
|
||||
assert(p2 != NULL);
|
||||
ptrdiff_t d = (const char *)p1 - (const char *)p2;
|
||||
if (p1 >= p2)
|
||||
assert(mem_size_valid_bytes(d));
|
||||
else
|
||||
assert(mem_size_valid_bytes(-d));
|
||||
return ACC_ICONV(int, d);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// bool use_simple_mcheck()
|
||||
**************************************************************************/
|
||||
|
|
|
@ -614,7 +614,7 @@ class PeFile::ImportLinker : public ElfLinkerAMD64
|
|||
unsigned len = 1 + 2 * strlen(dll) + 1 + 2 * strlen(proc) + 1 + 1;
|
||||
tstr dlln(name_for_dll(dll, first_char));
|
||||
char *procn = New(char, len);
|
||||
upx_snprintf(procn, len - 1, "%s%c", (const char*) dlln, separator);
|
||||
upx_snprintf(procn, len, "%s%c", (const char*) dlln, separator);
|
||||
encode_name(proc, procn + strlen(procn));
|
||||
return procn;
|
||||
}
|
||||
|
|
|
@ -745,35 +745,35 @@ static size_t dopr(char *buffer, size_t maxsize, const char *format, va_list arg
|
|||
**************************************************************************/
|
||||
|
||||
// UPX version with assertions
|
||||
int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap) {
|
||||
int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap) {
|
||||
size_t size;
|
||||
|
||||
// preconditions
|
||||
assert(count <= UPX_RSIZE_MAX_STR);
|
||||
assert(max_size <= UPX_RSIZE_MAX_STR);
|
||||
if (str != NULL)
|
||||
assert(count > 0);
|
||||
assert(max_size > 0);
|
||||
else
|
||||
assert(count == 0);
|
||||
assert(max_size == 0);
|
||||
|
||||
size = dopr(str, count, format, ap);
|
||||
size = dopr(str, max_size, format, ap);
|
||||
|
||||
// postconditions
|
||||
assert(size > 0);
|
||||
assert(size <= UPX_RSIZE_MAX_STR);
|
||||
if (str != NULL) {
|
||||
assert(size <= count);
|
||||
assert(size <= max_size);
|
||||
assert(str[size - 1] == '\0');
|
||||
}
|
||||
|
||||
return ACC_ICONV(int, size - 1); // snprintf() returns length, not size
|
||||
}
|
||||
|
||||
int __acc_cdecl_va upx_snprintf(char *str, size_t count, const char *format, ...) {
|
||||
int __acc_cdecl_va upx_snprintf(char *str, upx_rsize_t max_size, const char *format, ...) {
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
va_start(ap, format);
|
||||
len = upx_vsnprintf(str, count, format, ap);
|
||||
len = upx_vsnprintf(str, max_size, format, ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
|
|
|
@ -28,31 +28,50 @@
|
|||
#ifndef __UPX_SNPRINTF_H
|
||||
#define __UPX_SNPRINTF_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_vsnprintf(char *str, size_t count, const char *format, va_list ap);
|
||||
int __acc_cdecl_va upx_snprintf (char *str, size_t count, const char *format, ...);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// info: snprintf() returns length and NOT size, but max_size is indeed size (incl NUL)
|
||||
int upx_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap);
|
||||
int __acc_cdecl_va upx_snprintf (char *str, upx_rsize_t max_size, const char *format, ...);
|
||||
int upx_vasprintf(char **ptr, const char *format, va_list ap);
|
||||
int __acc_cdecl_va upx_asprintf (char **ptr, const char *format, ...);
|
||||
|
||||
#undef sprintf
|
||||
#define sprintf error_sprintf_is_dangerous_use_snprintf
|
||||
|
||||
upx_rsize_t upx_strlen(const char *);
|
||||
|
||||
#undef strlen
|
||||
#define strlen upx_strlen
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// globally redirect some functions
|
||||
#undef sprintf
|
||||
#define sprintf error_sprintf_is_dangerous_use_snprintf
|
||||
#undef strlen
|
||||
#define strlen upx_strlen
|
||||
|
||||
/*************************************************************************
|
||||
// some unsigned char string support functions
|
||||
**************************************************************************/
|
||||
|
||||
inline unsigned char *strcpy(unsigned char *s1, const unsigned char *s2) {
|
||||
return (unsigned char *) strcpy((char *) s1, (const char *) s2);
|
||||
}
|
||||
|
||||
inline int strcmp(const unsigned char *s1, const unsigned char *s2) {
|
||||
return strcmp((const char *) s1, (const char *) s2);
|
||||
}
|
||||
|
||||
inline int strcasecmp(const unsigned char *s1, const unsigned char *s2) {
|
||||
return strcasecmp((const char *) s1, (const char *) s2);
|
||||
}
|
||||
|
||||
inline size_t strlen(const unsigned char *s) { return strlen((const char *) s); }
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
|
66
src/util.cpp
66
src/util.cpp
|
@ -46,6 +46,72 @@
|
|||
#include "miniacc.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// assert sane memory buffer sizes to protect against integer overflows
|
||||
// and malicious header fields
|
||||
**************************************************************************/
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_MEM == UPX_RSIZE_MAX)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(UPX_RSIZE_MAX_STR <= UPX_RSIZE_MAX / 256)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(2ull * UPX_RSIZE_MAX * 9 / 8 + 16*1024*1024 < INT_MAX)
|
||||
|
||||
upx_rsize_t mem_size(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1, upx_uint64_t extra2)
|
||||
{
|
||||
assert(element_size > 0);
|
||||
if (element_size > UPX_RSIZE_MAX) throwCantPack("mem_size 1; take care");
|
||||
if (n > UPX_RSIZE_MAX) throwCantPack("mem_size 2; take care");
|
||||
if (extra1 > UPX_RSIZE_MAX) throwCantPack("mem_size 3; take care");
|
||||
if (extra2 > UPX_RSIZE_MAX) throwCantPack("mem_size 4; take care");
|
||||
upx_uint64_t bytes = element_size * n + extra1 + extra2; // cannot overflow
|
||||
if (bytes > UPX_RSIZE_MAX) throwCantPack("mem_size 5; take care");
|
||||
return ACC_ICONV(upx_rsize_t, bytes);
|
||||
}
|
||||
|
||||
upx_rsize_t mem_size_get_n(upx_uint64_t element_size, upx_uint64_t n)
|
||||
{
|
||||
mem_size_assert(element_size, n);
|
||||
return ACC_ICONV(upx_rsize_t, n); // return n
|
||||
}
|
||||
|
||||
bool mem_size_valid(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1, upx_uint64_t extra2)
|
||||
{
|
||||
assert(element_size > 0);
|
||||
if (element_size > UPX_RSIZE_MAX) return false;
|
||||
if (n > UPX_RSIZE_MAX) return false;
|
||||
if (extra1 > UPX_RSIZE_MAX) return false;
|
||||
if (extra2 > UPX_RSIZE_MAX) return false;
|
||||
upx_uint64_t bytes = element_size * n + extra1 + extra2; // cannot overflow
|
||||
if (bytes > UPX_RSIZE_MAX) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mem_size_valid_bytes(upx_uint64_t bytes)
|
||||
{
|
||||
if (bytes > UPX_RSIZE_MAX) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int ptr_diff(const void *p1, const void *p2)
|
||||
{
|
||||
assert(p1 != NULL);
|
||||
assert(p2 != NULL);
|
||||
ptrdiff_t d = (const char *)p1 - (const char *)p2;
|
||||
if (p1 >= p2)
|
||||
assert(mem_size_valid_bytes(d));
|
||||
else
|
||||
assert(mem_size_valid_bytes(-d));
|
||||
return ACC_ICONV(int, d);
|
||||
}
|
||||
|
||||
unsigned ptr_udiff(const void *p1, const void *p2)
|
||||
{
|
||||
int d = ptr_diff(p1, p2);
|
||||
assert(d >= 0);
|
||||
return ACC_ICONV(unsigned, d);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// bele.h
|
||||
**************************************************************************/
|
||||
|
|
68
src/util.h
68
src/util.h
|
@ -28,6 +28,28 @@
|
|||
#ifndef __UPX_UTIL_H
|
||||
#define __UPX_UTIL_H 1
|
||||
|
||||
/*************************************************************************
|
||||
// protect against integer overflows and malicious header fields
|
||||
**************************************************************************/
|
||||
|
||||
#define New(type, n) new type[mem_size_get_n(sizeof(type), n)]
|
||||
|
||||
upx_rsize_t mem_size(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1 = 0,
|
||||
upx_uint64_t extra2 = 0);
|
||||
upx_rsize_t mem_size_get_n(upx_uint64_t element_size, upx_uint64_t n);
|
||||
|
||||
inline void mem_size_assert(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1 = 0,
|
||||
upx_uint64_t extra2 = 0) {
|
||||
(void) mem_size(element_size, n, extra1, extra2); // sanity check
|
||||
}
|
||||
|
||||
bool mem_size_valid(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1 = 0,
|
||||
upx_uint64_t extra2 = 0);
|
||||
bool mem_size_valid_bytes(upx_uint64_t bytes);
|
||||
|
||||
int ptr_diff(const void *p1, const void *p2);
|
||||
unsigned ptr_udiff(const void *p1, const void *p2); // asserts p1 >= p2
|
||||
|
||||
/*************************************************************************
|
||||
// misc. support functions
|
||||
**************************************************************************/
|
||||
|
@ -56,52 +78,6 @@ int find_le64(const void *b, int blen, upx_uint64_t what);
|
|||
|
||||
int mem_replace(void *b, int blen, const void *what, int wlen, const void *r);
|
||||
|
||||
/*************************************************************************
|
||||
// protect against integer overflows and malicious header fields
|
||||
**************************************************************************/
|
||||
|
||||
upx_rsize_t mem_size(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1 = 0,
|
||||
upx_uint64_t extra2 = 0);
|
||||
upx_rsize_t mem_size_get_n(upx_uint64_t element_size, upx_uint64_t n);
|
||||
|
||||
inline void mem_size_assert(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1 = 0,
|
||||
upx_uint64_t extra2 = 0) {
|
||||
(void) mem_size(element_size, n, extra1, extra2); // sanity check
|
||||
}
|
||||
|
||||
bool mem_size_valid(upx_uint64_t element_size, upx_uint64_t n, upx_uint64_t extra1 = 0,
|
||||
upx_uint64_t extra2 = 0);
|
||||
bool mem_size_valid_bytes(upx_uint64_t bytes);
|
||||
|
||||
#define New(type, n) new type[mem_size_get_n(sizeof(type), n)]
|
||||
|
||||
int ptr_diff(const void *p1, const void *p2);
|
||||
|
||||
template <class T1, class T2>
|
||||
inline unsigned ptr_udiff(const T1 &p1, const T2 &p2) {
|
||||
int d = ptr_diff(p1, p2);
|
||||
assert(d >= 0);
|
||||
return ACC_ICONV(unsigned, d);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// some unsigned char string support functions
|
||||
**************************************************************************/
|
||||
|
||||
inline char *strcpy(unsigned char *s1, const unsigned char *s2) {
|
||||
return strcpy((char *) s1, (const char *) s2);
|
||||
}
|
||||
|
||||
inline int strcmp(const unsigned char *s1, const unsigned char *s2) {
|
||||
return strcmp((const char *) s1, (const char *) s2);
|
||||
}
|
||||
|
||||
inline int strcasecmp(const unsigned char *s1, const unsigned char *s2) {
|
||||
return strcasecmp((const char *) s1, (const char *) s2);
|
||||
}
|
||||
|
||||
inline size_t strlen(const unsigned char *s) { return strlen((const char *) s); }
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
|
Loading…
Reference in New Issue
Block a user