From 1d8b10d31aaf78e272a4dd43e7beffae5c6462df Mon Sep 17 00:00:00 2001 From: vovapi Date: Thu, 20 Feb 2020 17:36:15 +0300 Subject: [PATCH] hash/maphash: do not discard data on random seed init Hash initializes seed on the first usage of seed or state with initSeed. initSeed uses SetSeed which discards accumulated data. This causes hash to return different sums for the same data in the first use and after reset. This CL fixes this issue by separating the seed set from data discard. Fixes #37315 --- src/hash/maphash/maphash.go | 9 +++++++-- src/hash/maphash/maphash_test.go | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/hash/maphash/maphash.go b/src/hash/maphash/maphash.go index 4fef88e8ee..d99ed26a14 100644 --- a/src/hash/maphash/maphash.go +++ b/src/hash/maphash/maphash.go @@ -69,7 +69,7 @@ type Hash struct { // which does call h.initSeed.) func (h *Hash) initSeed() { if h.seed.s == 0 { - h.SetSeed(MakeSeed()) + h.setSeed(MakeSeed()) } } @@ -124,12 +124,17 @@ func (h *Hash) Seed() Seed { // Two Hash objects with different seeds will very likely behave differently. // Any bytes added to h before this call will be discarded. func (h *Hash) SetSeed(seed Seed) { + h.setSeed(seed) + h.n = 0 +} + +// setSeed sets seed without discarding accumulated data +func (h *Hash) setSeed(seed Seed) { if seed.s == 0 { panic("maphash: use of uninitialized Seed") } h.seed = seed h.state = seed - h.n = 0 } // Reset discards all bytes added to h. diff --git a/src/hash/maphash/maphash_test.go b/src/hash/maphash/maphash_test.go index 31d84a3b50..0164a9e20a 100644 --- a/src/hash/maphash/maphash_test.go +++ b/src/hash/maphash/maphash_test.go @@ -83,6 +83,29 @@ func TestHashHighBytes(t *testing.T) { } } +func TestRepeat(t *testing.T) { + h1 := new(Hash) + h1.WriteString("testing") + sum1 := h1.Sum64() + + h1.Reset() + h1.WriteString("testing") + sum2 := h1.Sum64() + + if sum1 != sum2 { + t.Errorf("different sum after reseting: %#x != %#x", sum1, sum2) + } + + h2 := new(Hash) + h2.SetSeed(h1.Seed()) + h2.WriteString("testing") + sum3 := h2.Sum64() + + if sum1 != sum3 { + t.Errorf("different sum on the same seed: %#x != %#x", sum1, sum3) + } +} + // Make sure a Hash implements the hash.Hash and hash.Hash64 interfaces. var _ hash.Hash = &Hash{} var _ hash.Hash64 = &Hash{}