Skip to content

Commit

Permalink
fix: Copy to an invalid addr but can set is not effective.
Browse files Browse the repository at this point in the history
  • Loading branch information
sineycoder committed Jun 21, 2022
1 parent 993be5b commit 71e2b36
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
17 changes: 16 additions & 1 deletion copier.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
15 changes: 15 additions & 0 deletions copier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

0 comments on commit 71e2b36

Please sign in to comment.