Skip to content

Commit 0693988

Browse files
authored
Fix unaligned memory access UB in compact_vector::access() (#11)
* Fix unaligned memory access UB in compact_vector::access() Replace reinterpret_cast + dereference with memcpy to avoid undefined behavior when accessing unaligned uint64_t values. This fixes crashes and incorrect behavior on ARM64 where unaligned access is not tolerated. The memcpy approach is standards-compliant and compilers optimize it to efficient code on all platforms. * fix UB in append_bits * Fix assert
1 parent 361ee92 commit 0693988

2 files changed

Lines changed: 5 additions & 1 deletion

File tree

include/bit_vector.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ struct bit_vector //
9797

9898
void append_bits(uint64_t bits, uint64_t len) {
9999
// check there are no spurious bits
100+
assert(len <= 64);
100101
assert(len == 64 || (bits >> len) == 0);
101102
if (!len) return;
102103
uint64_t pos_in_word = m_num_bits & 63;

include/compact_vector.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <vector>
44
#include <cmath>
5+
#include <cstring>
56
#include <iterator>
67

78
#include "essentials.hpp"
@@ -253,7 +254,9 @@ struct compact_vector //
253254
assert(i < size());
254255
uint64_t pos = i * m_width;
255256
const char* ptr = reinterpret_cast<const char*>(m_data.data());
256-
return (*(reinterpret_cast<uint64_t const*>(ptr + (pos >> 3))) >> (pos & 7)) & m_mask;
257+
uint64_t word;
258+
std::memcpy(&word, ptr + (pos >> 3), sizeof(uint64_t));
259+
return (word >> (pos & 7)) & m_mask;
257260
}
258261

259262
uint64_t back() const { return operator[](size() - 1); }

0 commit comments

Comments
 (0)