Skip to content

Commit 6e0fbb1

Browse files
authored
remove bound checks when decoding primitive runend arrays (#2251)
1 parent 3dcf882 commit 6e0fbb1

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

encodings/runend/src/compress.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,14 @@ pub fn runend_decode_typed_primitive<T: NativePType>(
184184
Mask::AllTrue(_) => {
185185
let mut decoded: BufferMut<T> = BufferMut::with_capacity(length);
186186
for (end, value) in run_ends.zip_eq(values) {
187-
decoded.push_n(*value, end - decoded.len());
187+
assert!(end <= length, "Runend end must be less than overall length");
188+
// SAFETY:
189+
// We preallocate enough capacity because we know the total length
190+
unsafe { decoded.push_n_unchecked(*value, end - decoded.len()) };
188191
}
189192
PrimitiveArray::new(decoded, values_nullability.into())
190193
}
191-
Mask::AllFalse(_) => {
192-
PrimitiveArray::new(buffer![T::default(); length], Validity::AllInvalid)
193-
}
194+
Mask::AllFalse(_) => PrimitiveArray::new(Buffer::<T>::zeroed(length), Validity::AllInvalid),
194195
Mask::Values(mask) => {
195196
let mut decoded = BufferMut::with_capacity(length);
196197
let mut decoded_validity = BooleanBufferBuilder::new(length);
@@ -200,14 +201,19 @@ pub fn runend_decode_typed_primitive<T: NativePType>(
200201
.zip(mask.boolean_buffer().iter())
201202
.map(|(&v, is_valid)| is_valid.then_some(v)),
202203
) {
204+
assert!(end <= length, "Runend end must be less than overall length");
203205
match value {
204206
None => {
205207
decoded_validity.append_n(end - decoded.len(), false);
206-
decoded.push_n(T::default(), end - decoded.len());
208+
// SAFETY:
209+
// We preallocate enough capacity because we know the total length
210+
unsafe { decoded.push_n_unchecked(T::default(), end - decoded.len()) };
207211
}
208212
Some(value) => {
209213
decoded_validity.append_n(end - decoded.len(), true);
210-
decoded.push_n(value, end - decoded.len());
214+
// SAFETY:
215+
// We preallocate enough capacity because we know the total length
216+
unsafe { decoded.push_n_unchecked(value, end - decoded.len()) };
211217
}
212218
}
213219
}

0 commit comments

Comments
 (0)