CI update: add ASAN/MSAN/valgrind checks
This commit is contained in:
@@ -571,6 +571,7 @@ TEST_CASE("working -fno-strict-aliasing") {
|
||||
*pi = -1;
|
||||
ok = *pl != 0;
|
||||
CHECK(ok);
|
||||
UNUSED(ok);
|
||||
}
|
||||
|
||||
TEST_CASE("working -fno-strict-overflow") {
|
||||
@@ -588,6 +589,7 @@ TEST_CASE("working -fno-strict-overflow") {
|
||||
i -= 1;
|
||||
ok = i == INT_MAX;
|
||||
CHECK(ok);
|
||||
UNUSED(ok);
|
||||
}
|
||||
|
||||
TEST_CASE("libc snprintf") {
|
||||
|
||||
@@ -43,6 +43,7 @@ TEST_CASE("raw_bytes ptr") {
|
||||
ptr = buf;
|
||||
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 1, 1), ptr) == 2u);
|
||||
CHECK(ptr_udiff_bytes(raw_index_bytes(ptr, 4, 0), ptr) == 8u);
|
||||
UNUSED(ptr);
|
||||
}
|
||||
|
||||
TEST_CASE("raw_bytes bounded array") {
|
||||
@@ -55,6 +56,7 @@ TEST_CASE("raw_bytes bounded array") {
|
||||
CHECK_THROWS(raw_index_bytes(buf, 3, 3));
|
||||
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 1, 1), buf) == 2u);
|
||||
CHECK(ptr_udiff_bytes(raw_index_bytes(buf, 4, 0), buf) == 8u);
|
||||
UNUSED(buf);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -405,6 +407,7 @@ TEST_CASE("PtrOrSpan") {
|
||||
CHECK_THROWS(sp_with_base = s0_no_base); // nullptr assignment
|
||||
CHECK_THROWS(sp_with_base = s0_with_base); // nullptr assignment
|
||||
#endif
|
||||
UNUSED(my_null);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -556,6 +559,7 @@ TEST_CASE("Span") {
|
||||
CHECK((XSPAN_S_MAKE(char, b1_b1).raw_base() == base_buf + 1));
|
||||
}
|
||||
#endif
|
||||
UNUSED(my_null);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -686,6 +690,7 @@ TEST_CASE("PtrOrSpan") {
|
||||
CHECK(my_memcmp_v1(buf, nullptr, 4) == -2);
|
||||
CHECK(my_memcmp_v2(buf + 4, buf + 4, 999) == 0);
|
||||
CHECK(my_memcmp_v2(buf, buf + 2, 3) == 0);
|
||||
UNUSED(buf);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -839,6 +844,7 @@ TEST_CASE("Span codegen") {
|
||||
CHECK(foo(XSPAN_0_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
|
||||
CHECK(foo(XSPAN_P_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
|
||||
CHECK(foo(XSPAN_S_MAKE(upx_uint8_t, buf, 8)) == 0 + 2 + 5 + 4 + 4 + 3);
|
||||
UNUSED(buf);
|
||||
}
|
||||
|
||||
#endif // WITH_XSPAN >= 2
|
||||
|
||||
@@ -547,6 +547,7 @@ TEST_CASE("upx_lzma_decompress") {
|
||||
d_len = 15;
|
||||
r = upx_lzma_decompress(c_data, 9, d_buf, &d_len, M_LZMA, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
UNUSED(r);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
@@ -363,6 +363,7 @@ TEST_CASE("upx_ucl_decompress") {
|
||||
d_len = 15;
|
||||
r = upx_ucl_decompress(c_data, 9, d_buf, &d_len, M_NRV2E_8, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
UNUSED(r);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
@@ -305,6 +305,7 @@ TEST_CASE("upx_zlib_decompress") {
|
||||
d_len = 15;
|
||||
r = upx_zlib_decompress(c_data, 6, d_buf, &d_len, M_DEFLATE, nullptr);
|
||||
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||
UNUSED(r);
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+15
-13
@@ -104,12 +104,11 @@ struct TriBool final {
|
||||
static_assert(ThirdValue != 0 && ThirdValue != 1);
|
||||
enum value_type : underlying_type { False = 0, True = 1, Third = ThirdValue };
|
||||
// constructors
|
||||
forceinline constexpr TriBool() noexcept : value(False) {}
|
||||
forceinline constexpr TriBool() noexcept {}
|
||||
forceinline constexpr TriBool(value_type x) noexcept : value(x) {}
|
||||
constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Third)) {}
|
||||
forceinline ~TriBool() noexcept = default;
|
||||
// access
|
||||
constexpr value_type getValue() const noexcept { return value; }
|
||||
// explicit conversion to bool
|
||||
// checks for > 0, so ThirdValue determines if Third is false (the default) or true
|
||||
explicit constexpr operator bool() const noexcept { return value > False; }
|
||||
// query; this is NOT the same as operator bool()
|
||||
@@ -117,19 +116,22 @@ struct TriBool final {
|
||||
constexpr bool isStrictTrue() const noexcept { return value == True; }
|
||||
constexpr bool isStrictBool() const noexcept { return value == False || value == True; }
|
||||
constexpr bool isThird() const noexcept { return value != False && value != True; }
|
||||
// access
|
||||
constexpr value_type getValue() const noexcept { return value; }
|
||||
// equality
|
||||
constexpr bool operator==(TriBool other) const noexcept { return value == other.value; }
|
||||
constexpr bool operator==(value_type other) const noexcept { return value == other; }
|
||||
constexpr bool operator==(promoted_type other) const noexcept { return value == other; }
|
||||
|
||||
// "third" can mean many things, depending on usage context, so provide some alternative names:
|
||||
// "Third" can mean many things, depending on usage context, so provide some alternative names:
|
||||
// constexpr bool isDefault() const noexcept { return isThird(); } // might be misleading
|
||||
constexpr bool isIndeterminate() const noexcept { return isThird(); }
|
||||
constexpr bool isOther() const noexcept { return isThird(); }
|
||||
constexpr bool isUndecided() const noexcept { return isThird(); }
|
||||
// constexpr bool isUnset() const noexcept { return isThird(); } // might be misleading
|
||||
|
||||
// protected:
|
||||
value_type value;
|
||||
private:
|
||||
value_type value = False; // the actual value of this type
|
||||
};
|
||||
|
||||
typedef TriBool<> tribool;
|
||||
@@ -147,6 +149,9 @@ struct OptVar final {
|
||||
static constexpr T max_value = max_value_;
|
||||
static_assert(min_value <= default_value && default_value <= max_value);
|
||||
|
||||
// automatic conversion
|
||||
constexpr operator T() const noexcept { return value; }
|
||||
|
||||
static void assertValue(const T &value) noexcept {
|
||||
// info: this generates annoying warnings "unsigned >= 0 is always true"
|
||||
// assert_noexcept(value >= min_value);
|
||||
@@ -155,7 +160,7 @@ struct OptVar final {
|
||||
}
|
||||
void assertValue() const noexcept { assertValue(value); }
|
||||
|
||||
constexpr OptVar() noexcept : value(default_value), is_set(false) {}
|
||||
constexpr OptVar() noexcept {}
|
||||
OptVar &operator=(const T &other) noexcept {
|
||||
assertValue(other);
|
||||
value = other;
|
||||
@@ -167,11 +172,9 @@ struct OptVar final {
|
||||
value = default_value;
|
||||
is_set = false;
|
||||
}
|
||||
constexpr operator T() const noexcept { return value; }
|
||||
|
||||
// protected:
|
||||
T value;
|
||||
bool is_set;
|
||||
value_type value = default_value;
|
||||
bool is_set = false;
|
||||
};
|
||||
|
||||
// optional assignments
|
||||
@@ -184,9 +187,8 @@ inline void oassign(OptVar<T, a, b, c> &self, const OptVar<T, a, b, c> &other) n
|
||||
}
|
||||
template <class T, T a, T b, T c>
|
||||
inline void oassign(T &v, const OptVar<T, a, b, c> &other) noexcept {
|
||||
if (other.is_set) {
|
||||
if (other.is_set)
|
||||
v = other.value;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
+5
-2
@@ -140,6 +140,7 @@ TEST_CASE("ptr_diff") {
|
||||
CHECK(ptr_udiff(buf, buf) == 0);
|
||||
CHECK(ptr_udiff(buf + 1, buf) == 1);
|
||||
CHECK_THROWS(ptr_udiff(buf, buf + 1));
|
||||
UNUSED(buf);
|
||||
}
|
||||
|
||||
// check that 2 buffers do not overlap; will throw on error
|
||||
@@ -174,7 +175,7 @@ void uintptr_check_no_overlap(upx_uintptr_t a, size_t a_size, upx_uintptr_t b, s
|
||||
throwCantPack("ptr_check_no_overlap-bc");
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
#if !defined(DOCTEST_CONFIG_DISABLE) && DEBUG
|
||||
TEST_CASE("ptr_check_no_overlap 2") {
|
||||
byte p[4] = {};
|
||||
|
||||
@@ -287,7 +288,7 @@ void upx_stable_sort(void *array, size_t n, size_t element_size,
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
#if !defined(DOCTEST_CONFIG_DISABLE) && DEBUG
|
||||
TEST_CASE("upx_stable_sort") {
|
||||
{
|
||||
unsigned a[] = {0, 1};
|
||||
@@ -518,6 +519,7 @@ TEST_CASE("find") {
|
||||
CHECK(find_le64(b, 16, 0x0f0e0d0c0b0a0908ULL) == 8);
|
||||
CHECK(find_be64(b, 15, 0x08090a0b0c0d0e0fULL) == -1);
|
||||
CHECK(find_le64(b, 15, 0x0f0e0d0c0b0a0908ULL) == -1);
|
||||
UNUSED(b);
|
||||
}
|
||||
|
||||
int mem_replace(void *buf, int blen, const void *what, int wlen, const void *replacement) noexcept {
|
||||
@@ -545,6 +547,7 @@ TEST_CASE("mem_replace") {
|
||||
CHECK(mem_replace(b + 8, 8, "bbb", 3, "efg") == 2);
|
||||
CHECK(mem_replace(b, 16, "b", 1, "h") == 2);
|
||||
CHECK(strcmp(b, "cdcdcdcdefgefghh") == 0);
|
||||
UNUSED(b);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
@@ -209,8 +209,8 @@ XSPAN_NAMESPACE_END
|
||||
// poison a pointer: point to a non-null invalid address
|
||||
// - resulting pointer should crash on dereference
|
||||
// - this should be efficient (so no mmap() guard page etc.)
|
||||
// - this should play nice with runtime checkers like ASAN, valgrind, etc.
|
||||
// - this should play nice with static analyzers like clang-tidy
|
||||
// - this should play nice with runtime checkers like ASAN, MSAN, valgrind, etc.
|
||||
// - this should play nice with static analyzers like clang-tidy etc.
|
||||
static forceinline void *XSPAN_GET_POISON_VOID_PTR() {
|
||||
// return (void *) (upx_uintptr_t) 251; // NOLINT(performance-no-int-to-ptr)
|
||||
return (void *) 251;
|
||||
|
||||
Reference in New Issue
Block a user