Skip to content

Commit f80cc5a

Browse files
authored
256bit Deserealization overflow fix
1 parent 57ee9e2 commit f80cc5a

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

src/bitset/serialization.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ where
2929
let mut block_indices: BlockIndices = unsafe{MaybeUninit::zeroed().assume_init()};
3030
mask.for_each_bit(|i|{
3131
block_indices.as_mut()[i] = *index_offset;
32-
*index_offset += Primitive::ONE;
32+
// Allowed to overflow here, on the very last round with
33+
// BlockIndices::Item=u8 and 256bit config.
34+
// (root level with 256 items)
35+
*index_offset = index_offset.wrapping_add(Primitive::ONE);
3336
});
3437
block_indices
3538
};

src/primitive.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub trait Primitive:
3636

3737
fn trailing_zeros(self) -> u32;
3838
fn wrapping_neg(self) -> Self;
39+
fn wrapping_add(self, rhs: Self) -> Self;
3940

4041
fn is_zero(self) -> bool;
4142
}
@@ -69,6 +70,11 @@ macro_rules! impl_primitive {
6970
self.wrapping_neg()
7071
}
7172

73+
#[inline]
74+
fn wrapping_add(self, rhs: Self) -> Self {
75+
self.wrapping_add(rhs)
76+
}
77+
7278
#[inline]
7379
fn is_zero(self) -> bool {
7480
self == 0

tests/serde.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use rand::{thread_rng, Rng};
22

3-
type BitSet = hi_sparse_bitset::BitSet<hi_sparse_bitset::config::_256bit>;
4-
3+
/// For issue https://github.com/tower120/hi_sparse_bitset/pull/47
54
#[test]
6-
fn serde() {
5+
#[cfg_attr(miri, ignore)]
6+
fn regression_deserialization_256bit_arithmetic_overflow() {
7+
type BitSet = hi_sparse_bitset::BitSet<hi_sparse_bitset::config::_256bit>;
8+
79
let mut rng = thread_rng();
810
let bitset: BitSet = (0..BitSet::max_capacity())
911
.filter(|_| rng.gen())

0 commit comments

Comments
 (0)