From c2e439e1af51cf89b16804e43445eabe725b2689 Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Sat, 4 Jul 2026 02:33:01 +0200 Subject: [PATCH 1/2] fix: panic if multiBufferBuilder UnsafeAppend truncates data --- arrow/array/bufferbuilder.go | 4 ++++ arrow/array/bufferbuilder_test.go | 38 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 arrow/array/bufferbuilder_test.go diff --git a/arrow/array/bufferbuilder.go b/arrow/array/bufferbuilder.go index 73183473c..93197da03 100644 --- a/arrow/array/bufferbuilder.go +++ b/arrow/array/bufferbuilder.go @@ -243,6 +243,10 @@ func (b *multiBufferBuilder) UnsafeAppend(hdr *arrow.ViewHeader, val []byte) { hdr.SetIndexOffset(int32(idx), int32(offset)) n := copy(buf.Buf()[offset:], val) + debug.Assert(n == len(val), "multibufferbuilder did not append full value") + if n != len(val) { + panic("arrow/array: multibufferbuilder could not append full value") + } buf.ResizeNoShrink(offset + n) } diff --git a/arrow/array/bufferbuilder_test.go b/arrow/array/bufferbuilder_test.go new file mode 100644 index 000000000..9a85686b5 --- /dev/null +++ b/arrow/array/bufferbuilder_test.go @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package array + +import ( + "testing" + + "github.com/apache/arrow-go/v18/arrow" + "github.com/apache/arrow-go/v18/arrow/memory" + "github.com/stretchr/testify/assert" +) + +func TestMultiBufferBuilderUnsafeAppendPanicsOnTruncatedCopy(t *testing.T) { + builder := multiBufferBuilder{mem: memory.NewGoAllocator(), blockSize: 8} + builder.Retain() + defer builder.Release() + + builder.Reserve(4) + + var hdr arrow.ViewHeader + assert.Panics(t, func() { + builder.UnsafeAppend(&hdr, []byte("abcdefghi")) + }) +} From a9c9b6cb258c0e341c7221464d8bb547ce1c68ae Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Sat, 4 Jul 2026 20:56:46 +0200 Subject: [PATCH 2/2] fix(multibufferbuilder): make unsafe append truncation test realistic --- arrow/array/bufferbuilder.go | 1 - arrow/array/bufferbuilder_test.go | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arrow/array/bufferbuilder.go b/arrow/array/bufferbuilder.go index 93197da03..a4d5e0431 100644 --- a/arrow/array/bufferbuilder.go +++ b/arrow/array/bufferbuilder.go @@ -243,7 +243,6 @@ func (b *multiBufferBuilder) UnsafeAppend(hdr *arrow.ViewHeader, val []byte) { hdr.SetIndexOffset(int32(idx), int32(offset)) n := copy(buf.Buf()[offset:], val) - debug.Assert(n == len(val), "multibufferbuilder did not append full value") if n != len(val) { panic("arrow/array: multibufferbuilder could not append full value") } diff --git a/arrow/array/bufferbuilder_test.go b/arrow/array/bufferbuilder_test.go index 9a85686b5..7acb55531 100644 --- a/arrow/array/bufferbuilder_test.go +++ b/arrow/array/bufferbuilder_test.go @@ -29,10 +29,13 @@ func TestMultiBufferBuilderUnsafeAppendPanicsOnTruncatedCopy(t *testing.T) { builder.Retain() defer builder.Release() - builder.Reserve(4) + buf := memory.NewResizableBuffer(builder.mem) + buf.ResizeNoShrink(1) + builder.blocks = []*memory.Buffer{buf} + builder.currentOutBuffer = 0 var hdr arrow.ViewHeader assert.Panics(t, func() { - builder.UnsafeAppend(&hdr, []byte("abcdefghi")) + builder.UnsafeAppend(&hdr, make([]byte, 64)) }) }