cmd/cloner: do not allocate slices when the source is nil

tailcfg.Node zero-value clone equality checks failed when I added a
[]*foo to the structure, as the zero value and it's clone contained a
different slice header.

Updates #9377
Updates #9408
Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker
2023-09-14 10:52:37 -07:00
committed by James Tucker
parent 85155ddaf3
commit 1858ad65c8
5 changed files with 57 additions and 33 deletions

View File

@@ -136,21 +136,29 @@ func (src *StructWithSlices) Clone() *StructWithSlices {
dst := new(StructWithSlices)
*dst = *src
dst.Values = append(src.Values[:0:0], src.Values...)
dst.ValuePointers = make([]*StructWithoutPtrs, len(src.ValuePointers))
for i := range dst.ValuePointers {
dst.ValuePointers[i] = src.ValuePointers[i].Clone()
if src.ValuePointers != nil {
dst.ValuePointers = make([]*StructWithoutPtrs, len(src.ValuePointers))
for i := range dst.ValuePointers {
dst.ValuePointers[i] = src.ValuePointers[i].Clone()
}
}
dst.StructPointers = make([]*StructWithPtrs, len(src.StructPointers))
for i := range dst.StructPointers {
dst.StructPointers[i] = src.StructPointers[i].Clone()
if src.StructPointers != nil {
dst.StructPointers = make([]*StructWithPtrs, len(src.StructPointers))
for i := range dst.StructPointers {
dst.StructPointers[i] = src.StructPointers[i].Clone()
}
}
dst.Structs = make([]StructWithPtrs, len(src.Structs))
for i := range dst.Structs {
dst.Structs[i] = *src.Structs[i].Clone()
if src.Structs != nil {
dst.Structs = make([]StructWithPtrs, len(src.Structs))
for i := range dst.Structs {
dst.Structs[i] = *src.Structs[i].Clone()
}
}
dst.Ints = make([]*int, len(src.Ints))
for i := range dst.Ints {
dst.Ints[i] = ptr.To(*src.Ints[i])
if src.Ints != nil {
dst.Ints = make([]*int, len(src.Ints))
for i := range dst.Ints {
dst.Ints[i] = ptr.To(*src.Ints[i])
}
}
dst.Slice = append(src.Slice[:0:0], src.Slice...)
dst.Prefixes = append(src.Prefixes[:0:0], src.Prefixes...)