-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Milestone
Description
Consider the following snippet:
v := reflect.ValueOf(struct {
m map[string]string // m is exported, we should never be able to get an interfaceable value of it or any sub-elements of it
}{m: map[string]string{"hello": "goodbye"}})
vm := v.FieldByName("m")
fmt.Println(vm.CanInterface()) // correctly prints false
ve := vm.MapIndex(reflect.ValueOf("hello"))
fmt.Println(ve.CanInterface()) // correctly prints false
ve = reflect.New(reflect.TypeOf("")).Elem()
for iter := vm.MapRange(); iter.Next(); {
ve.SetIterValue(iter) // incorrectly succeeds; expect panic due to read-only bit being false
vv := iter.Value() // older API for obtain a map value; it propagates the read-only bit check
fmt.Println(vv.CanInterface()) // correctly prints false
ve.Set(vv) // correctly panics
}
The newer Value.SetIterXXX
APIs added in Go 1.18 provide a way to circumvent the unexported field checks, thus allowing users to obtain an interfaceable value of an unexported field without the use of unsafe
.
bradfitz
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.The path to resolution is known, but the work has not been done.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.