Skip to content

Fuzzing Crash: Sum operation returns null for valid DecimalArray ChunkedArray #5810

@github-actions

Description

@github-actions

Fuzzing Crash Report

Analysis

Crash Location: fuzz/src/array/mod.rs:587 in assert_scalar_eq (called during Sum action validation)

Error Message:

Scalar mismatch: expected decimal256(22337414285953441061567344838540486740290084953887815750718056913398681145773, precision=76, scale=75), got null in step 1

Stack Trace:

   3: assert_scalar_eq
             at ./fuzz/src/array/mod.rs:705:13
   4: run_fuzz_action
             at ./fuzz/src/array/mod.rs:587:17
   5: __libfuzzer_sys_run
             at ./fuzz/fuzz_targets/array_ops.rs:14:11
   6: rust_fuzzer_test_input
             at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libfuzzer-sys-0.4.10/src/lib.rs:363:60

Root Cause:

The fuzzer discovered a bug where the sum operation on a ChunkedArray containing DecimalArrays returns a null scalar instead of the expected decimal value. The issue occurs with:

  • Array type: ChunkedArray with 2 chunks of DecimalArrays
  • Decimal dtype: Decimal(precision=76, scale=75, Nullable)
  • Values type: I256 (decimal256)
  • Operation: Sum operation (step 1)
  • Expected result: decimal256(22337414285953441061567344838540486740290084953887815750718056913398681145773, precision=76, scale=75)
  • Actual result: null

The ChunkedArray contains:

  1. First chunk: DecimalArray with 4 elements (I256 values, AllValid)
  2. Second chunk: DecimalArray with 3 elements (I256 values, AllValid)

All values are valid (no nulls), so the sum operation should return a valid decimal value. However, the sum operation is incorrectly returning null, suggesting a bug in either:

  1. The sum implementation for DecimalArray
  2. The sum implementation for ChunkedArray when dealing with decimal chunks
  3. Scalar value construction or type handling for large decimal256 values
  4. Overflow or precision handling during decimal summation
Debug Output
Output of `std::fmt::Debug`:

	FuzzArrayAction {
	    array: ChunkedArray {
	        dtype: Decimal(
	            DecimalDType {
	                precision: 76,
	                scale: 75,
	            },
	            Nullable,
	        ),
	        len: 7,
	        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: 96,
	                    alignment: Alignment(
	                        16,
	                    ),
	                    as_slice: [77, 71, 71, 71, 178, 71, 71, 255, 255, 79, 152, 30, 160, 222, 241, 221, ...],
	                },
	                values_type: I256,
	                validity: AllValid,
	                stats_set: ArrayStats {
	                    inner: RwLock {
	                        data: StatsSet {
	                            values: [],
	                        },
	                    },
	                },
	            },
	        ],
	        stats_set: ArrayStats {
	            inner: RwLock {
	                data: StatsSet {
	                    values: [],
	                },
	            },
	        },
	    },
	    actions: [
	        (
	            Sum,
	            Scalar(
	                Scalar {
	                    dtype: Decimal(
	                        DecimalDType {
	                            precision: 76,
	                            scale: 75,
	                        },
	                        Nullable,
	                    ),
	                    value: ScalarValue(
	                        Decimal(
	                            I256(
	                                i256(
	                                    22337414285953441061567344838540486740290084953887815750718056913398681145773,
	                                ),
	                            ),
	                        ),
	                    ),
	                },
	            ),
	        ),
	        (
	            Sum,
	            Scalar(
	                Scalar {
	                    dtype: Decimal(
	                        DecimalDType {
	                            precision: 76,
	                            scale: 75,
	                        },
	                        Nullable,
	                    ),
	                    value: ScalarValue(
	                        Decimal(
	                            I256(
	                                i256(
	                                    22337414285953441061567344838540486740290084953887815750718056913398681145773,
	                                ),
	                            ),
	                        ),
	                    ),
	                },
	            ),
	        ),
	        (
	            Sum,
	            Scalar(
	                Scalar {
	                    dtype: Decimal(
	                        DecimalDType {
	                            precision: 76,
	                            scale: 75,
	                        },
	                        Nullable,
	                    ),
	                    value: ScalarValue(
	                        Decimal(
	                            I256(
	                                i256(
	                                    22337414285953441061567344838540486740290084953887815750718056913398681145773,
	                                ),
	                            ),
	                        ),
	                    ),
	                },
	            ),
	        ),
	        (
	            Sum,
	            Scalar(
	                Scalar {
	                    dtype: Decimal(
	                        DecimalDType {
	                            precision: 76,
	                            scale: 75,
	                        },
	                        Nullable,
	                    ),
	                    value: ScalarValue(
	                        Decimal(
	                            I256(
	                                i256(
	                                    22337414285953441061567344838540486740290084953887815750718056913398681145773,
	                                ),
	                            ),
	                        ),
	                    ),
	                },
	            ),
	        ),
	    ],
	}

Summary

  • Target: array_ops
  • Crash File: crash-8e17520b7a4059d336d944b96e615c0028bdc415
  • Branch: develop
  • Commit: 265f29a
  • Crash Artifact: (artifact URL not available)

Reproduction

  1. Download the crash artifact (if available)

  2. Reproduce locally:

# The artifact contains array_ops/crash-8e17520b7a4059d336d944b96e615c0028bdc415
cargo +nightly fuzz run -D --sanitizer=none array_ops array_ops/crash-8e17520b7a4059d336d944b96e615c0028bdc415 -- -rss_limit_mb=0
  1. Get full backtrace:
RUST_BACKTRACE=full cargo +nightly fuzz run -D --sanitizer=none array_ops array_ops/crash-8e17520b7a4059d336d944b96e615c0028bdc415 -- -rss_limit_mb=0

Auto-created by fuzzing workflow with Claude analysis

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions