From 0f098d731cc3b8942c29784a02612d13b0ca9381 Mon Sep 17 00:00:00 2001 From: Matthias Fulz Date: Sun, 3 Nov 2019 21:30:50 +0100 Subject: [PATCH] Fix: Handling of exported struct fields --- marshal.go | 15 +++++++++++++-- unmarshal.go | 15 +++++++++++++-- unsafe_marshal.go | 15 +++++++++++++-- unsafe_unmarshal.go | 15 +++++++++++++-- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/marshal.go b/marshal.go index 90f5b3c..de52cf1 100644 --- a/marshal.go +++ b/marshal.go @@ -244,11 +244,22 @@ func encRegister(e interface{}) (err error) { } encoderCache[string(t.Kind())] = f case reflect.Struct: + zt := reflect.New(t) + n := zt.Elem().NumField() + mfields := []int{} + for i := 0; i < n; i++ { + if zt.Elem().Field(i).CanSet() { + mfields = append(mfields, i) + } + } + if len(mfields) == 0 { + return errors.New("ssob: No exported fields for " + string(t.Name())) + } + f := func(e interface{}) (ret []byte, err error) { - n := v.NumField() bs := make([][]byte, n) blen := 0 - for i := 0; i < n; i++ { + for _, i := range mfields { bs[i], err = marshal(v.Field(i).Interface()) if err != nil { return nil, err diff --git a/unmarshal.go b/unmarshal.go index 813f987..c55b024 100644 --- a/unmarshal.go +++ b/unmarshal.go @@ -269,6 +269,18 @@ func decRegister(e interface{}) (err error) { } decoderCache[string(t.Kind())] = f case reflect.Struct: + zt := reflect.New(t) + n := zt.Elem().NumField() + mfields := []int{} + for i := 0; i < n; i++ { + if zt.Elem().Field(i).CanSet() { + mfields = append(mfields, i) + } + } + if len(mfields) == 0 { + return errors.New("ssob: No exported fields for " + string(t.Name())) + } + f := func(e interface{}, in []byte) (n int, err error) { t := reflect.TypeOf(e) v := reflect.ValueOf(e) @@ -279,8 +291,7 @@ func decRegister(e interface{}) (err error) { } vi := reflect.Indirect(v) - l := vi.NumField() - for i := 0; i < l; i++ { + for _, i := range mfields { ni, err := unmarshal(vi.Field(i).Addr().Interface(), in[pos:]) pos += ni if err != nil { diff --git a/unsafe_marshal.go b/unsafe_marshal.go index 7d3447d..a1cbfa5 100644 --- a/unsafe_marshal.go +++ b/unsafe_marshal.go @@ -354,11 +354,22 @@ func encRegisterUnsafe(e interface{}) (err error) { } unsafeEncoderCache[string(t.Kind())] = f case reflect.Struct: + zt := reflect.New(t) + n := zt.Elem().NumField() + mfields := []int{} + for i := 0; i < n; i++ { + if zt.Elem().Field(i).CanSet() { + mfields = append(mfields, i) + } + } + if len(mfields) == 0 { + return errors.New("ssob: No exported fields for " + string(t.Name())) + } + f := func(e interface{}) (ret []byte, err error) { - n := v.NumField() bs := make([][]byte, n) blen := 0 - for i := 0; i < n; i++ { + for _, i := range mfields { bs[i], err = unsafeMarshal(v.Field(i).Interface()) if err != nil { return nil, err diff --git a/unsafe_unmarshal.go b/unsafe_unmarshal.go index 2a8dcb0..51a7be6 100644 --- a/unsafe_unmarshal.go +++ b/unsafe_unmarshal.go @@ -396,6 +396,18 @@ func decRegisterUnsafe(e interface{}) (err error) { } unsafeDecoderCache[string(t.Kind())] = f case reflect.Struct: + zt := reflect.New(t) + n := zt.Elem().NumField() + mfields := []int{} + for i := 0; i < n; i++ { + if zt.Elem().Field(i).CanSet() { + mfields = append(mfields, i) + } + } + if len(mfields) == 0 { + return errors.New("ssob: No exported fields for " + string(t.Name())) + } + f := func(e interface{}, in []byte) (n int, err error) { t := reflect.TypeOf(e) v := reflect.ValueOf(e) @@ -406,8 +418,7 @@ func decRegisterUnsafe(e interface{}) (err error) { } vi := reflect.Indirect(v) - l := vi.NumField() - for i := 0; i < l; i++ { + for _, i := range mfields { ni, err := unsafeUnmarshal(vi.Field(i).Addr().Interface(), in[pos:]) pos += ni if err != nil {