cmd/cloner: deep-clone pointer elements in map-of-slice values
The cloner's codegen for map[K][]*V fields was doing a shallow append (copying pointer values) instead of cloning each element. This meant that cloned structs aliased the original's pointed-to values through the map's slice entries. Mirror the existing standalone-slice logic that checks ContainsPointers(sliceType.Elem()) and generates per-element cloning for pointer, interface, and struct types. Regenerate net/dns and tailcfg which both had affected map[...][]*dnstype.Resolver fields. Fixes #19284 Signed-off-by: Andrew Dunham <andrew@tailscale.com>
This commit is contained in:
committed by
Andrew Dunham
parent
47ecbe5845
commit
d52ae45e9b
@@ -96,14 +96,34 @@ func (src *Map) Clone() *Map {
|
||||
dst.StructWithoutPtr = maps.Clone(src.StructWithoutPtr)
|
||||
if dst.SlicesWithPtrs != nil {
|
||||
dst.SlicesWithPtrs = map[string][]*StructWithPtrs{}
|
||||
for k := range src.SlicesWithPtrs {
|
||||
dst.SlicesWithPtrs[k] = append([]*StructWithPtrs{}, src.SlicesWithPtrs[k]...)
|
||||
for k, sv := range src.SlicesWithPtrs {
|
||||
if sv == nil {
|
||||
continue
|
||||
}
|
||||
dst.SlicesWithPtrs[k] = make([]*StructWithPtrs, len(sv))
|
||||
for i := range sv {
|
||||
if sv[i] == nil {
|
||||
dst.SlicesWithPtrs[k][i] = nil
|
||||
} else {
|
||||
dst.SlicesWithPtrs[k][i] = sv[i].Clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if dst.SlicesWithoutPtrs != nil {
|
||||
dst.SlicesWithoutPtrs = map[string][]*StructWithoutPtrs{}
|
||||
for k := range src.SlicesWithoutPtrs {
|
||||
dst.SlicesWithoutPtrs[k] = append([]*StructWithoutPtrs{}, src.SlicesWithoutPtrs[k]...)
|
||||
for k, sv := range src.SlicesWithoutPtrs {
|
||||
if sv == nil {
|
||||
continue
|
||||
}
|
||||
dst.SlicesWithoutPtrs[k] = make([]*StructWithoutPtrs, len(sv))
|
||||
for i := range sv {
|
||||
if sv[i] == nil {
|
||||
dst.SlicesWithoutPtrs[k][i] = nil
|
||||
} else {
|
||||
dst.SlicesWithoutPtrs[k][i] = new(*sv[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dst.StructWithoutPtrKey = maps.Clone(src.StructWithoutPtrKey)
|
||||
@@ -115,8 +135,18 @@ func (src *Map) Clone() *Map {
|
||||
}
|
||||
if dst.SliceIntPtr != nil {
|
||||
dst.SliceIntPtr = map[string][]*int{}
|
||||
for k := range src.SliceIntPtr {
|
||||
dst.SliceIntPtr[k] = append([]*int{}, src.SliceIntPtr[k]...)
|
||||
for k, sv := range src.SliceIntPtr {
|
||||
if sv == nil {
|
||||
continue
|
||||
}
|
||||
dst.SliceIntPtr[k] = make([]*int, len(sv))
|
||||
for i := range sv {
|
||||
if sv[i] == nil {
|
||||
dst.SliceIntPtr[k][i] = nil
|
||||
} else {
|
||||
dst.SliceIntPtr[k][i] = new(*sv[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dst.PointerKey = maps.Clone(src.PointerKey)
|
||||
@@ -399,8 +429,14 @@ func (src *GenericCloneableStruct[T, V]) Clone() *GenericCloneableStruct[T, V] {
|
||||
}
|
||||
if dst.SliceMap != nil {
|
||||
dst.SliceMap = map[string][]T{}
|
||||
for k := range src.SliceMap {
|
||||
dst.SliceMap[k] = append([]T{}, src.SliceMap[k]...)
|
||||
for k, sv := range src.SliceMap {
|
||||
if sv == nil {
|
||||
continue
|
||||
}
|
||||
dst.SliceMap[k] = make([]T, len(sv))
|
||||
for i := range sv {
|
||||
dst.SliceMap[k][i] = sv[i].Clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
return dst
|
||||
@@ -500,14 +536,34 @@ func (src *StructWithTypeAliasFields) Clone() *StructWithTypeAliasFields {
|
||||
}
|
||||
if dst.MapOfSlicesWithPtrs != nil {
|
||||
dst.MapOfSlicesWithPtrs = map[string][]*StructWithPtrsAlias{}
|
||||
for k := range src.MapOfSlicesWithPtrs {
|
||||
dst.MapOfSlicesWithPtrs[k] = append([]*StructWithPtrsAlias{}, src.MapOfSlicesWithPtrs[k]...)
|
||||
for k, sv := range src.MapOfSlicesWithPtrs {
|
||||
if sv == nil {
|
||||
continue
|
||||
}
|
||||
dst.MapOfSlicesWithPtrs[k] = make([]*StructWithPtrsAlias, len(sv))
|
||||
for i := range sv {
|
||||
if sv[i] == nil {
|
||||
dst.MapOfSlicesWithPtrs[k][i] = nil
|
||||
} else {
|
||||
dst.MapOfSlicesWithPtrs[k][i] = sv[i].Clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if dst.MapOfSlicesWithoutPtrs != nil {
|
||||
dst.MapOfSlicesWithoutPtrs = map[string][]*StructWithoutPtrsAlias{}
|
||||
for k := range src.MapOfSlicesWithoutPtrs {
|
||||
dst.MapOfSlicesWithoutPtrs[k] = append([]*StructWithoutPtrsAlias{}, src.MapOfSlicesWithoutPtrs[k]...)
|
||||
for k, sv := range src.MapOfSlicesWithoutPtrs {
|
||||
if sv == nil {
|
||||
continue
|
||||
}
|
||||
dst.MapOfSlicesWithoutPtrs[k] = make([]*StructWithoutPtrsAlias, len(sv))
|
||||
for i := range sv {
|
||||
if sv[i] == nil {
|
||||
dst.MapOfSlicesWithoutPtrs[k][i] = nil
|
||||
} else {
|
||||
dst.MapOfSlicesWithoutPtrs[k][i] = new(*sv[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dst
|
||||
|
||||
Reference in New Issue
Block a user