Skip to content

Commit aa215ce

Browse files
committed
Linting fixes and alignment testing
Clippy wants explicit types on transmute calls (reasonable). Fixed issue where from_raw_parts was upset about misaligned slices. I think for all platforms we're targetting the alignment of the buckets doesn't matter. This was fixed by not casting the byte buffer pointer to the correct type and instead transmuting after the fact. Fix alignment and unsafe transmutes The changes focus on making alignment handling more safe and explicit in unsafe code blocks, while also adding test coverage for alignment issues. Fix unsafe transmutes and alignment in bitvec module The changes improve type safety in unsafe transmutes and add alignment tests for raw pointer conversions. This fixes potential undefined behavior when converting between slice types.
1 parent fc9c45d commit aa215ce

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

crates/geo_filters/src/diff_count.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ impl<C: GeoConfig<Diff>> Count<Diff> for GeoDiffCount<'_, C> {
371371

372372
#[cfg(test)]
373373
mod tests {
374+
use std::io::Write;
375+
374376
use itertools::Itertools;
375377
use rand::{seq::IteratorRandom, RngCore, SeedableRng};
376378

@@ -627,9 +629,18 @@ mod tests {
627629
}
628630

629631
let mut writer = vec![];
632+
633+
// Insert some padding to emulate alignment issues with the slices
634+
// A previous version of this test never panicked even though we were
635+
// violating the alignment preconditions for the `from_raw_parts` function
636+
let pad = (0..8).choose(&mut rnd).unwrap();
637+
for _ in 0..pad {
638+
writer.write(&[0x0]).unwrap();
639+
}
640+
630641
before.write(&mut writer).unwrap();
631642

632-
let after = GeoDiffCount::<'_, C>::from_bytes(before.config.clone(), &writer);
643+
let after = GeoDiffCount::<'_, C>::from_bytes(before.config.clone(), &writer[pad..]);
633644

634645
assert_eq!(before, after);
635646
}

crates/geo_filters/src/diff_count/bitvec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl BitVec<'_> {
172172
);
173173

174174
let blocks = unsafe {
175-
std::mem::transmute(std::slice::from_raw_parts(
175+
std::mem::transmute::<&[u8], &[u64]>(std::slice::from_raw_parts(
176176
buf.as_ptr(),
177177
buf.len() / BYTES_PER_BLOCK,
178178
))

crates/geo_filters/src/diff_count/serde.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@ impl<'a, C: GeoConfig<Diff>> GeoDiffCount<'a, C> {
2727
// The number of most significant bits stores in the MSB sparse repr
2828
let msb_len = (buf.len() / size_of::<C::BucketType>()).min(c.max_msb_len());
2929

30-
let msb =
31-
unsafe { std::slice::from_raw_parts(buf.as_ptr() as *const C::BucketType, msb_len) };
30+
let msb = unsafe {
31+
std::mem::transmute::<&[u8], &[C::BucketType]>(std::slice::from_raw_parts(
32+
buf.as_ptr(),
33+
msb_len,
34+
))
35+
};
3236

3337
// The number of bytes representing the MSB - this is how many bytes we need to
3438
// skip over to reach the LSB
@@ -55,10 +59,7 @@ impl<'a, C: GeoConfig<Diff>> GeoDiffCount<'a, C> {
5559

5660
let msb_buckets = self.msb.deref();
5761
let msb_bytes = unsafe {
58-
std::slice::from_raw_parts(
59-
msb_buckets.as_ptr() as *const u8,
60-
msb_buckets.len() * size_of::<C::BucketType>(),
61-
)
62+
std::slice::from_raw_parts(msb_buckets.as_ptr() as *const u8, size_of_val(msb_buckets))
6263
};
6364
writer.write_all(msb_bytes)?;
6465

0 commit comments

Comments
 (0)