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 c69c0ecd fix(arrow/scalar): reject negative array lengths (#1024)
c69c0ecd is described below
commit c69c0ecd5a4f701ed16c3cc30468217a7abc981f
Author: Minh Vu <[email protected]>
AuthorDate: Mon Jul 27 22:30:58 2026 +0200
fix(arrow/scalar): reject negative array lengths (#1024)
### Rationale for this change
`MakeArrayFromScalar` accepts a signed length and returns an error, but
negative lengths are not rejected consistently. For valid scalars, a
negative length reaches buffer allocation and panics with a runtime
slice-bounds error. For null scalars, it silently returns a corrupt
array carrying a negative length.
### What changes are included in this PR?
* Reject negative lengths before either the null-scalar or valid-scalar
path.
* Return an error wrapping `arrow.ErrInvalid` before allocating any
buffers.
### Are these changes tested?
Yes. The regression test covers both valid and null scalars with a
negative length and verifies that both return `arrow.ErrInvalid` without
allocating memory.
---
arrow/scalar/scalar.go | 4 ++++
arrow/scalar/scalar_test.go | 11 +++++++++++
2 files changed, 15 insertions(+)
diff --git a/arrow/scalar/scalar.go b/arrow/scalar/scalar.go
index f4fcbab7..dff4c2ed 100644
--- a/arrow/scalar/scalar.go
+++ b/arrow/scalar/scalar.go
@@ -794,6 +794,10 @@ func MakeArrayOfNull(dt arrow.DataType, length int, mem
memory.Allocator) arrow.
// MakeArrayFromScalar returns an array filled with the scalar value repeated
length times.
// Not yet implemented for nested types such as Struct, List, extension and so
on.
func MakeArrayFromScalar(sc Scalar, length int, mem memory.Allocator)
(arrow.Array, error) {
+ if length < 0 {
+ return nil, fmt.Errorf("%w: array length must be non-negative,
got %d", arrow.ErrInvalid, length)
+ }
+
if !sc.IsValid() {
return MakeArrayOfNull(sc.DataType(), length, mem), nil
}
diff --git a/arrow/scalar/scalar_test.go b/arrow/scalar/scalar_test.go
index 1d321d47..78ec0c9a 100644
--- a/arrow/scalar/scalar_test.go
+++ b/arrow/scalar/scalar_test.go
@@ -1134,6 +1134,17 @@ func TestMakeArrayFromScalar(t *testing.T) {
}
}
+func TestMakeArrayFromScalarRejectsNegativeLength(t *testing.T) {
+ mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
+ defer mem.AssertSize(t, 0)
+
+ for _, sc := range []scalar.Scalar{scalar.NewInt32Scalar(1),
scalar.ScalarNull} {
+ arr, err := scalar.MakeArrayFromScalar(sc, -1, mem)
+ require.ErrorIs(t, err, arrow.ErrInvalid)
+ assert.Nil(t, arr)
+ }
+}
+
type OptionListTest struct {
FieldNames []string `compute:"field_names"`
FieldNulls []bool `compute:"field_null"`