From 331ad84c27b6fc45e993c5000e561685d693d52a Mon Sep 17 00:00:00 2001 From: Florent Hivert Date: Mon, 23 Oct 2023 13:44:52 +0200 Subject: [PATCH] Fixed out-of-bound access (issue #21) --- include/epu_impl.hpp | 4 ++-- include/perm16_impl.hpp | 12 ++++++------ tests/test_perm_all.cpp | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/epu_impl.hpp b/include/epu_impl.hpp index a7d23318..0a2d7f40 100644 --- a/include/epu_impl.hpp +++ b/include/epu_impl.hpp @@ -475,8 +475,8 @@ template <> struct not_equal_to { template <> struct hash { inline size_t operator()(HPCombi::epu8 a) const { - __int128 v0 = _mm_extract_epi64(a, 0); - __int128 v1 = _mm_extract_epi64(a, 1); + unsigned __int128 v0 = _mm_extract_epi64(a, 0); + unsigned __int128 v1 = _mm_extract_epi64(a, 1); return ((v1 * HPCombi::prime + v0) * HPCombi::prime) >> 64; /* The following is extremely slow on Renner benchmark diff --git a/include/perm16_impl.hpp b/include/perm16_impl.hpp index 3e66a6aa..365f4f6f 100644 --- a/include/perm16_impl.hpp +++ b/include/perm16_impl.hpp @@ -68,12 +68,12 @@ inline PTransf16 PTransf16::left_one() const { } inline uint32_t PTransf16::rank_ref() const { TPUBuild::array tmp{}; - for (size_t i = 0; i < 16; i++) - tmp[v[i]] = 1; - uint32_t res = 0; - for (size_t i = 0; i < 16; i++) - res += tmp[i]; - return res; + static_assert(TPUBuild::size == 16, "Wrong size of EPU8 array"); + for (size_t i = 0; i < 16; i++) { + if (v[i] != 0xFF) + tmp[v[i]] = 1; + } + return std::accumulate(tmp.begin(), tmp.end(), uint8_t(0)); } inline uint32_t PTransf16::rank() const { return _mm_popcnt_u32(image_bitset()); diff --git a/tests/test_perm_all.cpp b/tests/test_perm_all.cpp index 553d6c91..2267761c 100644 --- a/tests/test_perm_all.cpp +++ b/tests/test_perm_all.cpp @@ -63,6 +63,9 @@ struct Fixture : public IsPermFunctions { static bool not_less(const VectType a, const VectType b) { return not(a < b); }; + + // some tests assume that the size is at least 6 + static_assert(VectType::Size() >= 6, "Minimum size for tests"); }; //____________________________________________________________________________// @@ -97,7 +100,10 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(equal_test, F, Fixtures, F) { BOOST_FIXTURE_TEST_CASE_TEMPLATE(operator_bracket_const_test, F, Fixtures, F) { BOOST_TEST(F::czero[0] == 0u); BOOST_TEST(F::czero[1] == 0u); - BOOST_TEST(F::czero[15] == 0u); + if (F::czero.Size() > 12) + BOOST_TEST(F::czero[12] == 0u); + if (F::czero.Size() > 15) + BOOST_TEST(F::czero[15] == 0u); BOOST_TEST(F::cV01[0] == 0u); BOOST_TEST(F::cV01[1] == 1u); BOOST_TEST(F::cV01[2] == 0u); @@ -106,7 +112,10 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(operator_bracket_const_test, F, Fixtures, F) { BOOST_FIXTURE_TEST_CASE_TEMPLATE(operator_bracket_test, F, Fixtures, F) { BOOST_TEST(F::zero[0] == 0u); BOOST_TEST(F::zero[1] == 0u); - BOOST_TEST(F::zero[15] == 0u); + if (F::czero.Size() > 12) + BOOST_TEST(F::zero[12] == 0u); + if (F::czero.Size() > 15) + BOOST_TEST(F::zero[15] == 0u); BOOST_TEST(F::V01[0] == 0u); BOOST_TEST(F::V01[1] == 1u); BOOST_TEST(F::V01[2] == 0u); @@ -115,7 +124,10 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(operator_bracket_test, F, Fixtures, F) { F::zero[0] = 3; BOOST_TEST(F::zero[0] == 3u); BOOST_TEST(F::zero[1] == 0u); - BOOST_TEST(F::zero[15] == 0u); + if (F::czero.Size() > 12) + BOOST_TEST(F::zero[12] == 0u); + if (F::czero.Size() > 15) + BOOST_TEST(F::zero[15] == 0u); F::PPa[2] = 0; BOOST_TEST(F::PPa[1] == 2u); BOOST_TEST(F::PPa[2] == 0u);