This is an automated email from the ASF dual-hosted git repository.

hubcio pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git


The following commit(s) were added to refs/heads/master by this push:
     new 140f3c5f1 fix(go): return error instead of panic on S2 decode failure 
(#3166)
140f3c5f1 is described below

commit 140f3c5f16c20991e675f55417bdadf0e8ab3f0d
Author: Atharva Lade <[email protected]>
AuthorDate: Wed May 6 06:07:32 2026 -0500

    fix(go): return error instead of panic on S2 decode failure (#3166)
---
 .../binary_response_deserializer.go                |  2 +-
 .../binary_response_deserializer_test.go           | 88 ++++++++++++++++++++++
 2 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/foreign/go/binary_serialization/binary_response_deserializer.go 
b/foreign/go/binary_serialization/binary_response_deserializer.go
index 045073f55..3de147010 100644
--- a/foreign/go/binary_serialization/binary_response_deserializer.go
+++ b/foreign/go/binary_serialization/binary_response_deserializer.go
@@ -157,7 +157,7 @@ func DeserializeFetchMessagesResponse(payload []byte, 
compression iggcon.IggyMes
                        }
                        payloadSlice, err = s2.Decode(nil, payloadSlice)
                        if err != nil {
-                               panic("iggy: failed to decode s2 payload: " + 
err.Error())
+                               return nil, fmt.Errorf("failed to decode s2 
payload: %w", err)
                        }
                }
 
diff --git 
a/foreign/go/binary_serialization/binary_response_deserializer_test.go 
b/foreign/go/binary_serialization/binary_response_deserializer_test.go
new file mode 100644
index 000000000..1b4c0c023
--- /dev/null
+++ b/foreign/go/binary_serialization/binary_response_deserializer_test.go
@@ -0,0 +1,88 @@
+// 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 binaryserialization
+
+import (
+       "encoding/binary"
+       "strings"
+       "testing"
+
+       iggcon "github.com/apache/iggy/foreign/go/contracts"
+)
+
+func buildFetchPayload(payloadBody []byte) []byte {
+       header := iggcon.NewMessageHeader(iggcon.MessageID{}, 
uint32(len(payloadBody)), 0)
+       headerBytes := header.ToBytes()
+
+       // 4 (partitionId) + 8 (currentOffset) + 4 (messagesCount) + header + 
body
+       buf := make([]byte, 16+len(headerBytes)+len(payloadBody))
+       binary.LittleEndian.PutUint32(buf[0:4], 1)
+       binary.LittleEndian.PutUint64(buf[4:12], 0)
+       binary.LittleEndian.PutUint32(buf[12:16], 1)
+       copy(buf[16:], headerBytes)
+       copy(buf[16+len(headerBytes):], payloadBody)
+       return buf
+}
+
+func TestDeserializeFetchMessages_MalformedS2ReturnsError(t *testing.T) {
+       garbage := []byte{0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01, 0x02, 0x03,
+               0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8,
+               0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
+               0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x00}
+       payload := buildFetchPayload(garbage)
+
+       result, err := DeserializeFetchMessagesResponse(payload, 
iggcon.MESSAGE_COMPRESSION_S2)
+
+       if result != nil {
+               t.Errorf("expected nil result, got %+v", result)
+       }
+       if err == nil {
+               t.Fatal("expected error for malformed S2 payload, got nil")
+       }
+       if !strings.Contains(err.Error(), "failed to decode s2 payload") {
+               t.Errorf("error message %q does not mention S2 decode failure", 
err.Error())
+       }
+}
+
+func TestDeserializeFetchMessages_NoCompressionSkipsS2(t *testing.T) {
+       body := []byte("hello world")
+       payload := buildFetchPayload(body)
+
+       result, err := DeserializeFetchMessagesResponse(payload, 
iggcon.MESSAGE_COMPRESSION_NONE)
+
+       if err != nil {
+               t.Fatalf("unexpected error: %v", err)
+       }
+       if len(result.Messages) != 1 {
+               t.Fatalf("expected 1 message, got %d", len(result.Messages))
+       }
+       if string(result.Messages[0].Payload) != "hello world" {
+               t.Errorf("payload = %q, want %q", result.Messages[0].Payload, 
"hello world")
+       }
+}
+
+func TestDeserializeFetchMessages_EmptyPayload(t *testing.T) {
+       result, err := DeserializeFetchMessagesResponse([]byte{}, 
iggcon.MESSAGE_COMPRESSION_S2)
+
+       if err != nil {
+               t.Fatalf("unexpected error: %v", err)
+       }
+       if len(result.Messages) != 0 {
+               t.Fatalf("expected 0 messages, got %d", len(result.Messages))
+       }
+}

Reply via email to