util/sha256x: make Hash.Sum non-escaping (#5338)

Since Hash is a concrete type, we can make it such that
Sum never escapes the input.

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
pull/5339/head
Joe Tsai 2 years ago committed by GitHub
parent 76b0e578c5
commit 1c3c6b5382
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -45,10 +45,19 @@ func (h *Hash) Sum(b []byte) []byte {
h.h.Write(h.x[:h.nx]) h.h.Write(h.x[:h.nx])
h.nx = 0 h.nx = 0
} }
return h.h.Sum(b)
// Unfortunately hash.Hash.Sum always causes the input to escape since
// escape analysis cannot prove anything past an interface method call.
// Assuming h already escapes, we call Sum with h.x first,
// and then the copy the result to b.
sum := h.h.Sum(h.x[:0])
return append(b, sum...)
} }
func (h *Hash) Reset() { func (h *Hash) Reset() {
if h.h == nil {
h.h = sha256.New()
}
h.h.Reset() h.h.Reset()
h.nx = 0 h.nx = 0
} }

@ -64,6 +64,7 @@ func hashSuite(h hasher) {
h.HashBytes(bytes[:(i+1)*13]) h.HashBytes(bytes[:(i+1)*13])
} }
} }
func Test(t *testing.T) { func Test(t *testing.T) {
c := qt.New(t) c := qt.New(t)
h1 := New() h1 := New()
@ -73,6 +74,16 @@ func Test(t *testing.T) {
c.Assert(h1.Sum(nil), qt.DeepEquals, h2.Sum(nil)) c.Assert(h1.Sum(nil), qt.DeepEquals, h2.Sum(nil))
} }
func TestSumAllocations(t *testing.T) {
c := qt.New(t)
h := New()
n := testing.AllocsPerRun(100, func() {
var a [sha256.Size]byte
h.Sum(a[:0])
})
c.Assert(n, qt.Equals, 0.0)
}
func Fuzz(f *testing.F) { func Fuzz(f *testing.F) {
f.Fuzz(func(t *testing.T, seed int64) { f.Fuzz(func(t *testing.T, seed int64) {
c := qt.New(t) c := qt.New(t)

Loading…
Cancel
Save