Skip to content

Commit

Permalink
Fix memory leak from hex.DecodeString
Browse files Browse the repository at this point in the history
  • Loading branch information
rillig committed Jan 18, 2019
1 parent a25b794 commit eb05804
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
15 changes: 13 additions & 2 deletions distinfo.go
Expand Up @@ -179,17 +179,28 @@ func (ck *distinfoLinesChecker) checkGlobalDistfileMismatch(line Line, filename,
otherHash := hashes[key]

hashBytes, err := hex.DecodeString(hash)

// As of Go 1.11.4 in January 2019, hex.DecodeString has a memory leak.
// Instead of allocating a byte slice half the length of the given string
// it allocates a byte array of the length of the whole string and then
// returns the first half of it. The latter half then contains a copy of the
// original string, leaking that information into heap dumps and wasting heap memory.
//
// Free the unnecessary memory by copying the byte slice again.
newBytes := make([]byte, len(hashBytes))
copy(newBytes, hashBytes)

if err != nil {
line.Errorf("The %s hash for %s contains a non-hex character.", alg, filename)
}

if otherHash != nil {
if !bytes.Equal(otherHash.hash, hashBytes) {
if !bytes.Equal(otherHash.hash, newBytes) {
line.Errorf("The %s hash for %s is %s, which conflicts with %s in %s.",
alg, filename, hash, hex.EncodeToString(otherHash.hash), line.RefToLocation(otherHash.location))
}
} else {
hashes[key] = &Hash{hashBytes, line.Location}
hashes[key] = &Hash{newBytes, line.Location}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions distinfo_test.go
Expand Up @@ -84,9 +84,9 @@ func (s *Suite) Test_distinfoLinesChecker_checkGlobalDistfileMismatch(c *check.C
"WARN: ~/licenses/gnu-gpl-v2: This license seems to be unused.",
"5 errors and 1 warning found.")

// Ensure that hex.DecodeString does not waste memory here.
t.Check(len(G.Pkgsrc.Hashes["SHA512:distfile-1.0.tar.gz"].hash), equals, 8)
// FIXME: Must be 8, since the binary hash is only 8 bytes long.
t.Check(cap(G.Pkgsrc.Hashes["SHA512:distfile-1.0.tar.gz"].hash), equals, 16)
t.Check(cap(G.Pkgsrc.Hashes["SHA512:distfile-1.0.tar.gz"].hash), equals, 8)
}

func (s *Suite) Test_CheckLinesDistinfo__uncommitted_patch(c *check.C) {
Expand Down

0 comments on commit eb05804

Please sign in to comment.