types/change: fix slice aliasing in Change.Merge

Merge copies the receiver by value, but the slice headers share the
backing array with the original. When append has spare capacity, it
writes through to the original's memory, and uniqueNodeIDs then
sorts that shared data in place.

Replace append with slices.Concat which always allocates a fresh
backing array, preventing mutation of the receiver's slices.
This commit is contained in:
Kristoffer Dalby
2026-04-02 13:10:20 +00:00
committed by Kristoffer Dalby
parent 157e3a30fc
commit 2a2d5c869a

View File

@@ -66,9 +66,9 @@ func (r Change) Merge(other Change) Change {
merged.SendAllPeers = r.SendAllPeers || other.SendAllPeers
merged.RequiresRuntimePeerComputation = r.RequiresRuntimePeerComputation || other.RequiresRuntimePeerComputation
merged.PeersChanged = uniqueNodeIDs(append(r.PeersChanged, other.PeersChanged...))
merged.PeersRemoved = uniqueNodeIDs(append(r.PeersRemoved, other.PeersRemoved...))
merged.PeerPatches = append(r.PeerPatches, other.PeerPatches...)
merged.PeersChanged = uniqueNodeIDs(slices.Concat(r.PeersChanged, other.PeersChanged))
merged.PeersRemoved = uniqueNodeIDs(slices.Concat(r.PeersRemoved, other.PeersRemoved))
merged.PeerPatches = slices.Concat(r.PeerPatches, other.PeerPatches)
// Preserve OriginNode for self-update detection.
// If either change has OriginNode set, keep it so the mapper