From 71e2b36cb855da302dc1eadf82c0fd86ff80534b Mon Sep 17 00:00:00 2001 From: sineycoder Date: Tue, 21 Jun 2022 17:05:22 +0800 Subject: [PATCH 1/2] fix: Copy to an invalid addr but can set is not effective. --- copier.go | 17 ++++++++++++++++- copier_test.go | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/copier.go b/copier.go index 286ddb6..9fe463a 100644 --- a/copier.go +++ b/copier.go @@ -102,7 +102,12 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) ) if !to.CanAddr() { - return ErrInvalidCopyDestination + toPtr := preIndirect(reflect.ValueOf(toValue)) + if !toPtr.CanSet() { + return ErrInvalidCopyDestination + } + to = reflect.New(toPtr.Type().Elem()) + toPtr.Set(to) } // Return is from value is invalid @@ -433,6 +438,16 @@ func deepFields(reflectType reflect.Type) []reflect.StructField { return res } +func preIndirect(reflectValue reflect.Value) reflect.Value { + for reflectValue.Kind() == reflect.Ptr { + if !reflectValue.Elem().CanAddr() { + break + } + reflectValue = reflectValue.Elem() + } + return reflectValue +} + func indirect(reflectValue reflect.Value) reflect.Value { for reflectValue.Kind() == reflect.Ptr { reflectValue = reflectValue.Elem() diff --git a/copier_test.go b/copier_test.go index 4cc85b4..f1fdb70 100644 --- a/copier_test.go +++ b/copier_test.go @@ -1666,3 +1666,18 @@ func TestSqlNullFiled(t *testing.T) { t.Errorf("to (%v) value should equal from (%v) value", to.MkExpiryDateType, from.MkExpiryDateType.Int32) } } + +func TestCopy(t *testing.T) { + now := time.Now() + age := int32(28) + src := &User{ + Age: 14, + Name: "tom", + Birthday: &now, + FakeAge: &age, + Notes: []string{"hello"}, + } + var tar *User + err := copier.Copy(&tar, src) + fmt.Println(err, tar, reflect.DeepEqual(src, tar)) +} From 7afe0ac5cf3800daff9a2425eba01d28702fdfc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=80=AA=E6=8C=AF=E8=B4=A4?= Date: Tue, 21 Jun 2022 17:40:07 +0800 Subject: [PATCH 2/2] fix: Copy to an invalid addr but can set is not effective. --- copier.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/copier.go b/copier.go index 9fe463a..a933d62 100644 --- a/copier.go +++ b/copier.go @@ -108,6 +108,10 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) } to = reflect.New(toPtr.Type().Elem()) toPtr.Set(to) + // reindirect + if to = indirect(reflect.ValueOf(toValue)); !to.CanAddr() { + return ErrInvalidCopyDestination + } } // Return is from value is invalid