FuzzArrayAction {
array: ListViewArray {
dtype: List(
List(
Decimal(
DecimalDType {
precision: 22,
scale: -49,
},
Nullable,
),
NonNullable,
),
NonNullable,
),
elements: ListViewArray {
dtype: List(
Decimal(
DecimalDType {
precision: 22,
scale: -49,
},
Nullable,
),
NonNullable,
),
elements: DecimalArray {
dtype: Decimal(
DecimalDType {
precision: 22,
scale: -49,
},
Nullable,
),
values: BufferHandle(
Host(
Buffer<u8> {
length: 0,
alignment: Alignment(
16,
),
as_slice: [],
},
),
),
values_type: I128,
validity: AllValid,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
offsets: PrimitiveArray {
dtype: Primitive(
U64,
NonNullable,
),
buffer: BufferHandle(
Host(
Buffer<u8> {
length: 0,
alignment: Alignment(
8,
),
as_slice: [],
},
),
),
validity: NonNullable,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [
(
IsSorted,
Exact(
ScalarValue(
Bool(
true,
),
),
),
),
],
},
},
},
},
sizes: PrimitiveArray {
dtype: Primitive(
U64,
NonNullable,
),
buffer: BufferHandle(
Host(
Buffer<u8> {
length: 0,
alignment: Alignment(
8,
),
as_slice: [],
},
),
),
validity: NonNullable,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
is_zero_copy_to_list: true,
validity: NonNullable,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
offsets: PrimitiveArray {
dtype: Primitive(
I16,
NonNullable,
),
buffer: BufferHandle(
Host(
Buffer<u8> {
length: 0,
alignment: Alignment(
2,
),
as_slice: [],
},
),
),
validity: NonNullable,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [
(
IsSorted,
Exact(
ScalarValue(
Bool(
true,
),
),
),
),
],
},
},
},
},
sizes: PrimitiveArray {
dtype: Primitive(
I16,
NonNullable,
),
buffer: BufferHandle(
Host(
Buffer<u8> {
length: 0,
alignment: Alignment(
2,
),
as_slice: [],
},
),
),
validity: NonNullable,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
is_zero_copy_to_list: true,
validity: NonNullable,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
actions: [
Compress(Default)
]
}
Fuzzing Crash Report
Analysis
Crash Location:
vortex-array/src/arrays/listview/conversion.rs:114in thelist_from_list_viewfunctionError Message:
Stack Trace:
Root Cause:
The bug is in
vortex-array/src/arrays/listview/rebuild.rs. Thelist_from_list_viewfunction callsrebuild(ListViewRebuildMode::MakeExact)and asserts that the result hasis_zero_copy_to_list() == true. However, the rebuild logic doesn't always preserve this property correctly.The issue occurs in the
rebuild_make_exactmethod (rebuild.rs:253-261):When the array already has
is_zero_copy_to_list() == true, it callsrebuild_trim_elements(). However,rebuild_trim_elements()(lines 194-251) can break the zero-copy property for edge cases like empty arrays or arrays with zero-length elements.At line 249,
rebuild_trim_elementspreserves the original flag:But when dealing with empty arrays (length 0), the calculations at lines 209-211 try to access
self.offset_at(self.len() - 1)which is problematic:Array Structure from Debug Output:
ListViewArraywithList(List(Decimal(...)))dtypeis_zero_copy_to_list: truesetDecimalArraywith empty values bufferThe crash occurs when BtrBlocks compression tries to convert this nested empty ListViewArray to a ListArray via
list_from_list_view.Debug Output
Summary
array_opscrash-608dbf18d00107ec105f15bdd29c17a20a5be099Reproduction
Download the crash artifact:
operations-fuzzing-crash-artifactsat: https://github.com/vortex-data/vortex/actions/runs/13746867682Reproduce locally:
# The artifact contains array_ops/crash-608dbf18d00107ec105f15bdd29c17a20a5be099 cargo +nightly fuzz run -D --sanitizer=none array_ops array_ops/crash-608dbf18d00107ec105f15bdd29c17a20a5be099 -- -rss_limit_mb=0Auto-created by fuzzing workflow with Claude analysis