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
This commit is contained in:
vovapi 2020-02-20 17:36:15 +03:00
parent 1cd724acb6
commit 1d8b10d31a
2 changed files with 30 additions and 2 deletions

View File

@ -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.

View File

@ -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{}