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:
Andrew Dunham
2026-04-07 20:52:09 +00:00
committed by Andrew Dunham
parent 47ecbe5845
commit d52ae45e9b
7 changed files with 217 additions and 42 deletions
+26
View File
@@ -182,6 +182,32 @@ func TestNamedMapContainer(t *testing.T) {
}
}
func TestMapSlicePointerContainer(t *testing.T) {
num := 42
orig := &clonerex.MapSlicePointerContainer{
Routes: map[string][]*clonerex.SliceContainer{
"route1": {
{Slice: []*int{&num}},
{Slice: []*int{&num, &num}},
},
"route2": {
{Slice: []*int{&num}},
},
},
}
cloned := orig.Clone()
if !reflect.DeepEqual(orig, cloned) {
t.Errorf("Clone() = %v, want %v", cloned, orig)
}
// Mutate cloned.Routes pointer values
*cloned.Routes["route1"][0].Slice[0] = 999
if *orig.Routes["route1"][0].Slice[0] == 999 {
t.Errorf("Clone() aliased memory in Routes: original was modified")
}
}
func TestDeeplyNestedMap(t *testing.T) {
num := 123
orig := &clonerex.DeeplyNestedMap{