Skip to content

GH-54570: [C++][Compute] Fix segfault casting null list with empty child to fixed_size_list - #54574

Open
ShivanshhhG wants to merge 1 commit into
apache:mainfrom
ShivanshhhG:fix-54570-cast-null-list-to-fixed-size-list
Open

ShivanshhhG wants to merge 1 commit into
apache:mainfrom
ShivanshhhG:fix-54570-cast-null-list-to-fixed-size-list

Conversation

@ShivanshhhG

Copy link
Copy Markdown

Rationale for this change

When casting a ListArray, LargeListArray, or ListViewArray to FixedSizeListArray, if the input array contains only null lists with an empty child array (which frequently occurs in IPC streams or deserialized batches from tools like Polars to_arrow()), cast_values->length is 0.

Previously, BuildTakeIndices populated index 0 for every null slot (builder.UnsafeAppend(0)). When Take was called with TakeOptions::NoBoundsCheck(), it attempted to access index 0 on an empty child array whose buffers may be null or unallocated, dereferencing a null pointer in FixedWidthTakeImpl and causing a segmentation fault (GH-54570).

What changes are included in this PR?

  1. If cast_values->length == 0, bypass Take entirely and directly create the output child array using MakeArrayOfNull(child_type, in_array.length * list_size, ctx->memory_pool()).
  2. In BuildTakeIndices, emit null indices (builder.UnsafeAppendNull()) for null list slots instead of index 0.
  3. Add regression tests in cpp/src/arrow/compute/kernels/scalar_cast_test.cc verifying that casting null lists with empty children (including unallocated child buffers) to FixedSizeList succeeds and produces the expected null list array.

Are these changes tested?

Yes, unit tests added to cpp/src/arrow/compute/kernels/scalar_cast_test.cc under TEST(Cast, ListToFSL).

Are there any user-facing changes?

No (fixes crash/segfault on valid spec-compliant input).

…pty child to fixed_size_list

When casting a ListArray or LargeListArray to FixedSizeListArray, if an array contains only null lists with an empty child array, cast_values->length is 0. Previously, BuildTakeIndices populated index 0 for null slots, and Take was called with TakeOptions::NoBoundsCheck(), dereferencing an unallocated child buffer and causing a segmentation fault.

This commit resolves the issue by:
1. Handling empty child values (cast_values->length == 0) directly using MakeArrayOfNull rather than attempting Take.
2. Emitting null indices (builder.UnsafeAppendNull()) for null list slots in BuildTakeIndices instead of index 0.
3. Adding regression tests for casting null lists with empty children and unallocated buffers to FixedSizeList.

Fixes: apache#54570

Signed-off-by: SHIVANSH-ux-ys <singaser78@gmail.com>
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #54570 has been automatically assigned in GitHub to PR creator.

@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #54570 has no components, please add labels for components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant