diff --git a/arrow/array/array.go b/arrow/array/array.go index 947b44f2..c47735fc 100644 --- a/arrow/array/array.go +++ b/arrow/array/array.go @@ -117,7 +117,11 @@ func invalidDataType(data arrow.ArrayData) arrow.Array { // MakeFromData constructs a strongly-typed array instance from generic Data. func MakeFromData(data arrow.ArrayData) arrow.Array { - return makeArrayFn[byte(data.DataType().ID()&0x3f)](data) + id := data.DataType().ID() + if id < 0 || int(id) >= len(makeArrayFn) || makeArrayFn[id] == nil { + return invalidDataType(data) + } + return makeArrayFn[id](data) } // NewSlice constructs a zero-copy slice of the array with the indicated diff --git a/arrow/array/array_test.go b/arrow/array/array_test.go index 9509e314..63e52a30 100644 --- a/arrow/array/array_test.go +++ b/arrow/array/array_test.go @@ -40,6 +40,7 @@ func (testDataType) Layout() arrow.DataTypeLayout { return arrow.DataTypeLayout{ func (testDataType) String() string { return "" } func TestMakeFromData(t *testing.T) { + const veryLargeTypeID arrow.Type = 1 << 30 tests := []struct { name string d arrow.DataType @@ -134,6 +135,10 @@ func TestMakeFromData(t *testing.T) { // invalid types {name: "invalid(-1)", d: &testDataType{arrow.Type(-1)}, expPanic: true, expError: "invalid data type: Type(-1)"}, {name: "invalid(63)", d: &testDataType{arrow.Type(63)}, expPanic: true, expError: "invalid data type: Type(63)"}, + {name: "invalid(64)", d: &testDataType{arrow.Type(64)}, expPanic: true, expError: "invalid data type: Type(64)"}, + {name: "invalid(65)", d: &testDataType{arrow.Type(65)}, expPanic: true, expError: "invalid data type: Type(65)"}, + {name: "invalid(127)", d: &testDataType{arrow.Type(127)}, expPanic: true, expError: "invalid data type: Type(127)"}, + {name: "invalid(very large)", d: &testDataType{veryLargeTypeID}, expPanic: true, expError: "invalid data type: Type(1073741824)"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) {