From d666bd85336a29e7bcf866e0a81cfaa263d1ae14 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Wed, 21 Jul 2021 11:29:08 -0700 Subject: [PATCH] util/deephash: disambiguate hashing of AppendTo (#2483) Prepend size to AppendTo output. Fixes #2443 Signed-off-by: Joe Tsai --- util/deephash/deephash.go | 6 ++++-- util/deephash/deephash_test.go | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/util/deephash/deephash.go b/util/deephash/deephash.go index 2c206b97e..61353ab91 100644 --- a/util/deephash/deephash.go +++ b/util/deephash/deephash.go @@ -147,8 +147,10 @@ func (h *hasher) print(v reflect.Value) (acyclic bool) { // Use AppendTo methods, if available and cheap. if v.CanAddr() && v.Type().Implements(appenderToType) { a := v.Addr().Interface().(appenderTo) - scratch := a.AppendTo(h.scratch[:0]) - w.Write(scratch) + size := h.scratch[:8] + record := a.AppendTo(size) + binary.LittleEndian.PutUint64(record, uint64(len(record)-len(size))) + w.Write(record) return true } } diff --git a/util/deephash/deephash_test.go b/util/deephash/deephash_test.go index 6576c3fa2..1579737d4 100644 --- a/util/deephash/deephash_test.go +++ b/util/deephash/deephash_test.go @@ -22,6 +22,12 @@ import ( "tailscale.com/wgengine/wgcfg" ) +type appendBytes []byte + +func (p appendBytes) AppendTo(b []byte) []byte { + return append(b, p...) +} + func TestHash(t *testing.T) { type tuple [2]interface{} type iface struct{ X interface{} } @@ -31,6 +37,8 @@ func TestHash(t *testing.T) { in tuple wantEq bool }{ + {in: tuple{[]appendBytes{{}, {0, 0, 0, 0, 0, 0, 0, 1}}, []appendBytes{{}, {0, 0, 0, 0, 0, 0, 0, 1}}}, wantEq: true}, + {in: tuple{[]appendBytes{{}, {0, 0, 0, 0, 0, 0, 0, 1}}, []appendBytes{{0, 0, 0, 0, 0, 0, 0, 1}, {}}}, wantEq: false}, {in: tuple{iface{MyBool(true)}, iface{MyBool(true)}}, wantEq: true}, {in: tuple{iface{true}, iface{MyBool(true)}}, wantEq: false}, {in: tuple{iface{MyHeader{}}, iface{MyHeader{}}}, wantEq: true},