-
Notifications
You must be signed in to change notification settings - Fork 109
Open
Description
Fuzzing Crash Report
Analysis
Crash Location: fuzz/src/array/mod.rs:assert_scalar_eq (line 721)
Error Message:
Scalar mismatch: expected decimal256(10335727954495815150286733452060801618349974312742667669043703035118638596109, precision=76, scale=75), got null in step 2
Stack Trace:
3: assert_scalar_eq
at ./fuzz/src/array/mod.rs:721:13
4: run_fuzz_action
at ./fuzz/src/array/mod.rs:600:17
5: __libfuzzer_sys_run
at ./fuzz/fuzz_targets/array_ops.rs:14:11
Root Cause: The fuzzer discovered an issue with the sum operation on decimal arrays after a mask operation. The test sequence:
- Created a ChunkedArray with Decimal(precision=76, scale=75) type containing 12 elements across 2 chunks
- Applied a mask operation with a bit pattern [248, 15] (9 true values out of 12, density 0.75)
- Attempted to compute the sum (step 2)
- Expected sum:
decimal256(10335727954495815150286733452060801618349974312742667669043703035118638596109, precision=76, scale=75) - Actual sum:
null
This suggests the sum operation may not be correctly handling decimal arrays after masking, possibly due to issues with null propagation or masked value handling in the decimal sum implementation.
Debug Output
FuzzArrayAction {
array: ChunkedArray {
dtype: Decimal(
DecimalDType {
precision: 76,
scale: 75,
},
Nullable,
),
len: 12,
chunk_offsets: PrimitiveArray {
dtype: Primitive(
U64,
NonNullable,
),
buffer: Buffer<u8> {
length: 24,
alignment: Alignment(
8,
),
as_slice: [0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, ...],
},
validity: NonNullable,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
chunks: [
DecimalArray {
dtype: Decimal(
DecimalDType {
precision: 76,
scale: 75,
},
Nullable,
),
values: Buffer<u8> {
length: 128,
alignment: Alignment(
16,
),
as_slice: [3, 0, 0, 0, 0, 0, 0, 0, 0, 144, 236, 228, 101, 118, 200, 187, ...],
},
values_type: I256,
validity: AllValid,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
DecimalArray {
dtype: Decimal(
DecimalDType {
precision: 76,
scale: 75,
},
Nullable,
),
values: Buffer<u8> {
length: 256,
alignment: Alignment(
16,
),
as_slice: [1, 0, 0, 0, 0, 0, 0, 0, 0, 208, 64, 171, 43, 14, 231, 224, ...],
},
values_type: I256,
validity: AllValid,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
],
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
actions: [
(
Mask(
Values(
MaskValues {
buffer: BitBuffer {
buffer: Buffer<u8> {
length: 2,
alignment: Alignment(
1,
),
as_slice: [248, 15],
},
offset: 0,
len: 12,
},
indices: OnceLock(
<uninit>,
),
slices: OnceLock(
<uninit>,
),
true_count: 9,
density: 0.75,
},
),
),
Array(
DecimalArray {
dtype: Decimal(
DecimalDType {
precision: 76,
scale: 75,
},
Nullable,
),
values: Buffer<u8> {
length: 384,
alignment: Alignment(
16,
),
as_slice: [3, 0, 0, 0, 0, 0, 0, 0, 0, 144, 236, 228, 101, 118, 200, 187, ...],
},
values_type: I256,
validity: Array(
BoolArray {
dtype: Bool(
NonNullable,
),
bits: BitBuffer {
buffer: Buffer<u8> {
length: 2,
alignment: Alignment(
1,
),
as_slice: [7, 240],
},
offset: 0,
len: 12,
},
validity: NonNullable,
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [
(
Sum,
Exact(
ScalarValue(
Primitive(
U64(
3,
),
),
),
),
),
],
},
},
},
},
),
stats_set: ArrayStats {
inner: RwLock {
data: StatsSet {
values: [],
},
},
},
},
),
),
(
Sum,
Scalar(
Scalar {
dtype: Decimal(
DecimalDType {
precision: 76,
scale: 75,
},
Nullable,
),
value: ScalarValue(
Decimal(
I256(
i256(
10335727954495815150286733452060801618349974312742667669043703035118638596109,
),
),
),
),
},
),
),
(
Sum,
Scalar(
Scalar {
dtype: Decimal(
DecimalDType {
precision: 76,
scale: 75,
},
Nullable,
),
value: ScalarValue(
Decimal(
I256(
i256(
10335727954495815150286733452060801618349974312742667669043703035118638596109,
),
),
),
),
},
),
),
],
}
Summary
- Target:
array_ops - Crash File:
crash-827867069cacb581ba8bb19ab6a0cd09d26dee48 - Branch: develop
- Commit: da5d463
- Crash Artifact: https://github.com/vortex-data/vortex/actions/runs/20679641682/artifacts/5014317923
Reproduction
-
Download the crash artifact:
- Direct download: https://github.com/vortex-data/vortex/actions/runs/20679641682/artifacts/5014317923
- Or find
operations-fuzzing-crash-artifactsat the workflow run - Extract the zip file
-
Reproduce locally:
# The artifact contains array_ops/crash-827867069cacb581ba8bb19ab6a0cd09d26dee48
cargo +nightly fuzz run -D --sanitizer=none array_ops array_ops/crash-827867069cacb581ba8bb19ab6a0cd09d26dee48 -- -rss_limit_mb=0- Get full backtrace:
RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops array_ops/crash-827867069cacb581ba8bb19ab6a0cd09d26dee48 -- -rss_limit_mb=0Auto-created by fuzzing workflow with Claude analysis