From 70b4e5ffaf46592bfa297c94b4ee7793e05c658d Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Sun, 30 Aug 2026 09:34:08 +0000 Subject: [PATCH] fix(attachment): skip unexported payload fields --- attachment.go | 6 ++++++ attachment_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/attachment.go b/attachment.go index 1617647..da20935 100644 --- a/attachment.go +++ b/attachment.go @@ -47,6 +47,9 @@ func encodeAttachmentValue(v reflect.Value, index *int) []io.Reader { if !v.IsValid() { return ret } + if !v.CanInterface() { + return ret + } switch v.Kind() { case reflect.Struct: if v.Type().Name() == "Attachment" { @@ -96,6 +99,9 @@ func decodeAttachmentValue(v reflect.Value, binary [][]byte) error { if !v.IsValid() { return fmt.Errorf("invalid value") } + if !v.CanInterface() { + return nil + } switch v.Kind() { case reflect.Struct: if v.Type().Name() == "Attachment" { diff --git a/attachment_test.go b/attachment_test.go index e63b88b..aa7e791 100644 --- a/attachment_test.go +++ b/attachment_test.go @@ -19,6 +19,11 @@ type HaveAttachment struct { A *Attachment `json:"a"` } +type HavePrivateAttachment struct { + A *Attachment `json:"a"` + hidden any +} + func TestEncodeAttachments(t *testing.T) { var input any var target []io.Reader @@ -103,6 +108,21 @@ func TestEncodeAttachments(t *testing.T) { So(string(b), ShouldEqual, `{"test":{"i":0,"a":{"_placeholder":true,"num":0}}}`) }) + Convey("Unexported fields are ignored", t, func() { + hidden := &Attachment{Data: buf2} + hidden.num = -1 + input = HavePrivateAttachment{ + A: attachment1, + hidden: hidden, + } + target = []io.Reader{buf1} + + test() + + So(attachment1.num, ShouldEqual, 0) + So(hidden.num, ShouldEqual, -1) + }) + } func TestDecodeAttachments(t *testing.T) { @@ -182,4 +202,21 @@ func TestDecodeAttachments(t *testing.T) { So(err, ShouldBeNil) So(v.A.num, ShouldEqual, 2) }) + + Convey("Unexported fields are ignored", t, func() { + input = [][]byte{[]byte("data1"), []byte("data2")} + hidden := &Attachment{Data: buf2} + hidden.num = 1 + attachment1 = &Attachment{Data: buf1} + attachment2 = nil + attachment1.num = 0 + v = HavePrivateAttachment{ + A: attachment1, + hidden: hidden, + } + + test() + + So(buf2.String(), ShouldBeEmpty) + }) }