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 279c7aec fix(arrow/util): handle invalid protobuf Any values (#1086)
279c7aec is described below

commit 279c7aec8a832a1bbd18ac6f65f1e7879462a797
Author: Minh Vu <[email protected]>
AuthorDate: Fri Aug 7 18:17:55 2026 +0200

    fix(arrow/util): handle invalid protobuf Any values (#1086)
    
    ### Rationale for this change
    
    An unknown protobuf Any type URL or invalid payload can leave the
    unpacked message nil. The schema conversion path then dereferences it
    instead of preserving the physical Any fields.
    
    ### What changes are included in this PR?
    
    Handle unpacking errors and fall back to reflecting type_url and value.
    Avoid copying protobuf message state during conversion.
    
    ### Are these changes tested?
    
    - `go test ./arrow/util`
    - go vet ./arrow/util
    - Added malformed Any schema and record coverage.
    
    ### Are there any user-facing changes?
    
    No API changes. This corrects the reported behavior while preserving the
    existing ownership and compatibility contracts.
---
 arrow/util/protobuf_reflect.go      | 14 ++++++++++----
 arrow/util/protobuf_reflect_test.go | 16 ++++++++++++++++
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/arrow/util/protobuf_reflect.go b/arrow/util/protobuf_reflect.go
index 6cd897b1..ca17c838 100644
--- a/arrow/util/protobuf_reflect.go
+++ b/arrow/util/protobuf_reflect.go
@@ -194,11 +194,17 @@ type ProtobufMessageReflection struct {
 
 func (psr ProtobufMessageReflection) unmarshallAny() ProtobufMessageReflection 
{
        if psr.descriptor.FullName() == "google.protobuf.Any" && 
psr.rValue.IsValid() {
-               for psr.rValue.Type().Kind() == reflect.Ptr {
-                       psr.rValue = reflect.Indirect(psr.rValue)
+               if !psr.message.IsValid() {
+                       return psr
+               }
+               fieldValueAsAny, ok := psr.message.Interface().(*anypb.Any)
+               if !ok {
+                       return psr
+               }
+               msg, err := fieldValueAsAny.UnmarshalNew()
+               if err != nil {
+                       return psr
                }
-               fieldValueAsAny, _ := psr.rValue.Interface().(anypb.Any)
-               msg, _ := fieldValueAsAny.UnmarshalNew()
 
                v := reflect.ValueOf(msg)
                for v.Kind() == reflect.Ptr {
diff --git a/arrow/util/protobuf_reflect_test.go 
b/arrow/util/protobuf_reflect_test.go
index 1f414405..c93331cd 100644
--- a/arrow/util/protobuf_reflect_test.go
+++ b/arrow/util/protobuf_reflect_test.go
@@ -350,6 +350,22 @@ func TestMapSchemaDoesNotDependOnValues(t *testing.T) {
        require.True(t, withValuesSchema.Equal(emptySchema))
 }
 
+func TestMalformedAnyUsesPhysicalFields(t *testing.T) {
+       msg := util_message.AllTheTypes{
+               Any: &anypb.Any{TypeUrl: "invalid.example/missing", Value: 
[]byte{1, 2, 3}},
+       }
+
+       pmr := NewProtobufMessageReflection(&msg)
+       anyFields := pmr.Schema().Field(17).Type.(*arrow.StructType).Fields()
+       require.Len(t, anyFields, 2)
+       assert.Equal(t, "type_url", anyFields[0].Name)
+       assert.Equal(t, "value", anyFields[1].Name)
+
+       rec := pmr.Record(nil)
+       defer rec.Release()
+       assert.EqualValues(t, 1, rec.NumRows())
+}
+
 func TestRecordFromProtobuf(t *testing.T) {
        f := AllTheTypesFixture()
 

Reply via email to