This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new c253857b fix(array): validate dense union offset lengths (#875)
c253857b is described below
commit c253857b6873a83ad7ca26be32ecb5b9d35b16ce
Author: Minh Vu <[email protected]>
AuthorDate: Wed Jul 1 18:20:02 2026 +0200
fix(array): validate dense union offset lengths (#875)
### What changed
NewDenseUnionFromArraysWithFieldCodes now rejects mismatched type ID and
offset lengths before constructing dense union data.
### Why
Dense unions use typeIDs.Len() as the logical length while borrowing the
offsets buffer. If the offsets array is shorter, later access can panic
or read invalid offset data; if it is longer, trailing offsets are
silently ignored.
### Validation
- go test ./arrow/array -run 'TestUnions/TestMakeDenseUnions' -count=1
- go test ./arrow/array -count=1
-
PARQUET_TEST_DATA=/Users/hoangvu/Code/OSS/arrow-go/parquet-testing/data
ARROW_TEST_DATA=/Users/hoangvu/Code/OSS/arrow-go/arrow-testing/data go
test ./... -count=1
---
arrow/array/union.go | 2 ++
arrow/array/union_test.go | 14 ++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/arrow/array/union.go b/arrow/array/union.go
index beaaf4e1..d9d18267 100644
--- a/arrow/array/union.go
+++ b/arrow/array/union.go
@@ -549,6 +549,8 @@ func NewDenseUnionFromArraysWithFieldCodes(typeIDs, offsets
arrow.Array, childre
return nil, errors.New("arrow/array: union typeIDs may not have
nulls")
case offsets.NullN() != 0:
return nil, errors.New("arrow/array: nulls are not allowed in
offsets for NewDenseUnionFromArrays*")
+ case typeIDs.Len() != offsets.Len():
+ return nil, errors.New("arrow/array: union typeIDs and offsets
must have the same length")
case len(fields) > 0 && len(fields) != len(children):
return nil, errors.New("arrow/array: fields must be the same
length as children")
case len(codes) > 0 && len(codes) != len(children):
diff --git a/arrow/array/union_test.go b/arrow/array/union_test.go
index aa03056a..5d975d57 100644
--- a/arrow/array/union_test.go
+++ b/arrow/array/union_test.go
@@ -457,6 +457,20 @@ func (s *UnionFactorySuite) TestMakeDenseUnions() {
defer result.Release()
s.Error(result.ValidateFull())
})
+
+ s.Run("mismatched type ids and offset lengths", func() {
+ shortOffsets := s.offsetsFromSlice(0, 0, 0, 1, 1, 0, 1, 2, 1)
+ defer shortOffsets.Release()
+ result, err := array.NewDenseUnionFromArrays(s.typeIDs,
shortOffsets, children)
+ s.Nil(result)
+ s.EqualError(err, "arrow/array: union typeIDs and offsets must
have the same length")
+
+ longOffsets := s.offsetsFromSlice(0, 0, 0, 1, 1, 0, 1, 2, 1, 2,
0)
+ defer longOffsets.Release()
+ result, err = array.NewDenseUnionFromArrays(s.typeIDs,
longOffsets, children)
+ s.Nil(result)
+ s.EqualError(err, "arrow/array: union typeIDs and offsets must
have the same length")
+ })
}
func (s *UnionFactorySuite) TestDenseUnionStringRoundTrip() {