Skip to content

Commit c7e88a2

Browse files
authored
fix: prevent potential out-of-range access in FixedSizeListArray (#5902)
* fix: prevent potential out-of-range access in FixedSizeListArray Signed-off-by: BubbleCal <[email protected]> * add benchmark & format Signed-off-by: BubbleCal <[email protected]> * format Cargo.toml Signed-off-by: BubbleCal <[email protected]> --------- Signed-off-by: BubbleCal <[email protected]>
1 parent d0a88c6 commit c7e88a2

File tree

3 files changed

+59
-4
lines changed

3 files changed

+59
-4
lines changed

arrow-array/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ harness = false
6666
[[bench]]
6767
name = "gc_view_types"
6868
harness = false
69+
70+
[[bench]]
71+
name = "fixed_size_list_array"
72+
harness = false
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
use arrow_array::{Array, FixedSizeListArray, Int32Array};
19+
use arrow_schema::Field;
20+
use criterion::*;
21+
use rand::{thread_rng, Rng};
22+
use std::sync::Arc;
23+
24+
fn gen_fsl(len: usize, value_len: usize) -> FixedSizeListArray {
25+
let mut rng = thread_rng();
26+
let values = Arc::new(Int32Array::from(
27+
(0..len).map(|_| rng.gen::<i32>()).collect::<Vec<_>>(),
28+
));
29+
let field = Arc::new(Field::new("item", values.data_type().clone(), true));
30+
FixedSizeListArray::new(field, value_len as i32, values, None)
31+
}
32+
33+
fn criterion_benchmark(c: &mut Criterion) {
34+
let len = 4096;
35+
for value_len in [1, 32, 1024] {
36+
let fsl = gen_fsl(len, value_len);
37+
c.bench_function(
38+
&format!("fixed_size_list_array(len: {len}, value_len: {value_len})"),
39+
|b| {
40+
b.iter(|| {
41+
for i in 0..len / value_len {
42+
black_box(fsl.value(i));
43+
}
44+
});
45+
},
46+
);
47+
}
48+
}
49+
50+
criterion_group!(benches, criterion_benchmark);
51+
criterion_main!(benches);

arrow-array/src/array/fixed_size_list_array.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,15 @@ impl FixedSizeListArray {
245245
/// Returns ith value of this list array.
246246
pub fn value(&self, i: usize) -> ArrayRef {
247247
self.values
248-
.slice(self.value_offset(i) as usize, self.value_length() as usize)
248+
.slice(self.value_offset_at(i), self.value_length() as usize)
249249
}
250250

251251
/// Returns the offset for value at index `i`.
252252
///
253253
/// Note this doesn't do any bound checking, for performance reason.
254254
#[inline]
255255
pub fn value_offset(&self, i: usize) -> i32 {
256-
self.value_offset_at(i)
256+
self.value_offset_at(i) as i32
257257
}
258258

259259
/// Returns the length for an element.
@@ -265,8 +265,8 @@ impl FixedSizeListArray {
265265
}
266266

267267
#[inline]
268-
const fn value_offset_at(&self, i: usize) -> i32 {
269-
i as i32 * self.value_length
268+
const fn value_offset_at(&self, i: usize) -> usize {
269+
i * self.value_length as usize
270270
}
271271

272272
/// Returns a zero-copy slice of this array with the indicated offset and length.

0 commit comments

Comments
 (0)