Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions arrow-buffer/src/util/bit_mask.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,18 @@ pub fn set_bits(
offset_read: usize,
len: usize,
) -> usize {
assert!(offset_write + len <= write_data.len() * 8);
assert!(offset_read + len <= data.len() * 8);
assert!(
offset_write
.checked_add(len)
.expect("operation will overflow write buffer")
<= write_data.len() * 8
);
assert!(
offset_read
.checked_add(len)
.expect("operation will overflow read buffer")
<= data.len() * 8
);
let mut null_count = 0;
let mut acc = 0;
while len > acc {
Expand Down Expand Up @@ -427,4 +437,40 @@ mod tests {
assert_eq!(len_set, 1);
assert_eq!(write_data, &[0b00000010]);
}

#[test]
#[should_panic(expected = "operation will overflow read buffer")]
fn test_overflow_read_buffer_bounds() {
// Tiny buffers so any huge computed index is out-of-bounds.
let data = [0u8; 1];
let mut write_data = [0u8; 1];

// Choose values so (offset_read + len) wraps to a small number in release builds.
// offset_read = usize::MAX - 7, len = 8 => wraps to 0.
// This can bypass `assert!(offset_read + len <= data.len() * 8)`.
let offset_write: usize = 0;
let offset_read: usize = usize::MAX - 7;
let len: usize = 8;

// should panic on bounds check overflow
let _nulls = set_bits(&mut write_data, &data, offset_write, offset_read, len);
}

#[test]
#[should_panic(expected = "operation will overflow write buffer")]
fn test_overflow_write_buffer_bounds() {
// Tiny buffers so any huge computed index is out-of-bounds.
let data = [0u8; 1];
let mut write_data = [0u8; 1];

// Choose values so (offset_write + len) wraps to a small number in release builds.
// offset_write = usize::MAX - 7, len = 8 => wraps to 0.
// This can bypass `assert!(offset_write + len <= write_data.len() * 8)`.
let offset_write: usize = usize::MAX - 7;
let offset_read: usize = 0;
let len: usize = 8;

// should panic on bounds check overflow
let _nulls = set_bits(&mut write_data, &data, offset_write, offset_read, len);
}
}
Loading