Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cpp/src/arrow/compute/kernels/copy_data_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ struct CopyDataUtils<BooleanType> {

static void CopyData(const DataType&, const ArraySpan& in, const int64_t in_offset,
uint8_t* out, const int64_t out_offset, const int64_t length) {
// Boolean values are bit-packed, so apply the array's offset to the bit index
// rather than to the data pointer.
const auto in_arr = in.GetValues<uint8_t>(1, /*absolute_offset=*/0);
CopyData(*in.type, in_arr, in_offset, out, out_offset, length);
CopyData(*in.type, in_arr, in.offset + in_offset, out, out_offset, length);
}
};

Expand Down
18 changes: 18 additions & 0 deletions cpp/src/arrow/compute/kernels/vector_replace_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,14 @@ TEST_F(TestReplaceBoolean, ReplaceWithMask) {
}
}

TEST_F(TestReplaceBoolean, ReplaceWithMaskSlicedInput) {
auto input =
this->array("[true, false, null, true, true, false, null, true]")->Slice(3, 5);

this->Assert(ReplaceWithMask, input, this->mask("[true, false, false, false, false]"),
this->array("[false]"), this->array("[false, true, false, null, true]"));
}

// Regression test: ReplaceMaskChunked (the ChunkedArray path of replace_with_mask)
// sized each output chunk's data buffer via byte_width(), which is 0 for boolean
// (bit-packed), the same GH-45086 buffer-overflow pattern fixed elsewhere in this
Expand Down Expand Up @@ -2117,6 +2125,16 @@ TYPED_TEST(TestFillNullBinary, FillBackwardChunkedArray) {
R"(["qup"])", R"(["qup", "mnz"])"}));
}

TEST_F(TestFillNullBoolean, FillNullSlicedArray) {
auto input =
this->array("[true, false, null, true, true, false, null, true]")->Slice(3, 5);

this->AssertFillNullArray(FillNullForward, input,
this->array("[true, true, false, false, true]"));
this->AssertFillNullArray(FillNullBackward, input,
this->array("[true, true, false, true, true]"));
}

// Regression test for GH-45086: FillNullForwardChunked/FillNullBackwardChunked
// size each output chunk's data buffer as `type->byte_width() * chunk->length()`.
// For BooleanType, byte_width() returns 0 (it is bit-packed, not byte-addressable),
Expand Down