if got := *y.Interface().(*int); got != b {
t.Errorf("pointer incorrect: got %d want %d", got, b)
}
+
+ // Make sure we panic assigning from an unexported field.
+ m = ValueOf(struct{ m map[string]int }{data}).Field(0)
+ for iter := m.MapRange(); iter.Next(); {
+ shouldPanic("using value obtained using unexported field", func() {
+ k.SetIterKey(iter)
+ })
+ shouldPanic("using value obtained using unexported field", func() {
+ v.SetIterValue(iter)
+ })
+ }
}
func TestMethodCallValueCodePtr(t *testing.T) {
// SetIterKey assigns to v the key of iter's current map entry.
// It is equivalent to v.Set(iter.Key()), but it avoids allocating a new Value.
-// As in Go, the key must be assignable to v's type.
+// As in Go, the key must be assignable to v's type and
+// must not be derived from an unexported field.
func (v Value) SetIterKey(iter *MapIter) {
if !iter.hiter.initialized() {
panic("reflect: Value.SetIterKey called before Next")
t := (*mapType)(unsafe.Pointer(iter.m.typ))
ktype := t.key
+ iter.m.mustBeExported() // do not let unexported m leak
key := Value{ktype, iterkey, iter.m.flag | flag(ktype.Kind()) | flagIndir}
key = key.assignTo("reflect.MapIter.SetKey", v.typ, target)
typedmemmove(v.typ, v.ptr, key.ptr)
// SetIterValue assigns to v the value of iter's current map entry.
// It is equivalent to v.Set(iter.Value()), but it avoids allocating a new Value.
-// As in Go, the value must be assignable to v's type.
+// As in Go, the value must be assignable to v's type and
+// must not be derived from an unexported field.
func (v Value) SetIterValue(iter *MapIter) {
if !iter.hiter.initialized() {
panic("reflect: Value.SetIterValue called before Next")
t := (*mapType)(unsafe.Pointer(iter.m.typ))
vtype := t.elem
+ iter.m.mustBeExported() // do not let unexported m leak
elem := Value{vtype, iterelem, iter.m.flag | flag(vtype.Kind()) | flagIndir}
elem = elem.assignTo("reflect.MapIter.SetValue", v.typ, target)
typedmemmove(v.typ, v.ptr, elem.ptr)
// Set assigns x to the value v.
// It panics if CanSet returns false.
-// As in Go, x's value must be assignable to v's type.
+// As in Go, x's value must be assignable to v's type and
+// must not be derived from an unexported field.
func (v Value) Set(x Value) {
v.mustBeAssignable()
x.mustBeExported() // do not let unexported x leak