Skip to content

Commit

Permalink
misc: fix UB in CPID hashing
Browse files Browse the repository at this point in the history
  • Loading branch information
div72 committed Oct 15, 2022
1 parent e4bc935 commit 3499e05
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 20 deletions.
18 changes: 13 additions & 5 deletions src/gridcoin/cpid.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,9 @@ namespace std {
//! This enables the use of GRC::Cpid as a key in a std::unordered_map object.
//!
//! CONSENSUS: Don't use the hash produced by this routine (or by any std::hash
//! specialization) in protocol-specific implementations. It ignores endianness
//! and outputs a value with a chance of collision probably too great for usage
//! besides the intended local look-up functionality.
//! specialization) in protocol-specific implementations. It outputs a value
//! with a chance of collision probably too great for usage besides the intended
//! local look-up functionality.
//!
template<>
struct hash<GRC::Cpid>
Expand All @@ -473,8 +473,16 @@ struct hash<GRC::Cpid>
// Just convert the CPID into a value that we can store in a size_t
// object. CPIDs are already unique identifiers.
//
return *reinterpret_cast<const uint64_t*>(cpid.Raw().data())
+ *reinterpret_cast<const uint64_t*>(cpid.Raw().data() + 8);
const auto& data = cpid.Raw();
size_t ret = ((size_t)(data[0] & 255) | (size_t)(data[1] & 255) << 8 |
(size_t)(data[2] & 255) << 16 | (size_t)(data[3] & 255) << 24);

if (sizeof(size_t) == 8) {
ret |= ((size_t)(data[4] & 255) << 32 | (size_t)(data[5] & 255) << 40 |
(size_t)(data[6] & 255) << 48 | (size_t)(data[7] & 255) << 56);
}

return ret;
}
};
}
Expand Down
15 changes: 0 additions & 15 deletions src/test/gridcoin/cpid_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,21 +239,6 @@ BOOST_AUTO_TEST_CASE(it_deserializes_from_a_stream)
BOOST_CHECK(bytes == expected);
}

BOOST_AUTO_TEST_CASE(it_is_hashable_to_key_a_lookup_map)
{
GRC::Cpid cpid(std::vector<unsigned char> {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
});

std::hash<GRC::Cpid> hasher;

// CPID halves, little endian
const size_t expected = static_cast<size_t>(0x0706050403020100ull + 0x1514131211100908ull);

BOOST_CHECK_EQUAL(hasher(cpid), expected);
}

BOOST_AUTO_TEST_SUITE_END()

// -----------------------------------------------------------------------------
Expand Down

0 comments on commit 3499e05

Please sign in to comment.