From 10a4605ec28d31952c187f339752e9f508795f63 Mon Sep 17 00:00:00 2001 From: Stephen J Day Date: Tue, 13 Jan 2015 21:35:42 -0800 Subject: [PATCH] Explicitly select digest method for content Detecting tar files then falling back for calculating digests turned out to be fairly unreliable. Likely, the implementation was broken for content that was not a tarfile. Also, for the use case of the registry, it is really not needed. This functionality has been removed in FromReader and FromBytes. FromTarArchive has been added for convenience. Signed-off-by: Stephen J Day --- digest/digest.go | 36 ++++++++++++++++-------------------- digest/verifiers_test.go | 2 +- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/digest/digest.go b/digest/digest.go index a5d5b5a8..40f1db15 100644 --- a/digest/digest.go +++ b/digest/digest.go @@ -36,6 +36,11 @@ func NewDigest(alg string, h hash.Hash) Digest { return Digest(fmt.Sprintf("%s:%x", alg, h.Sum(nil))) } +// NewDigestFromHex returns a Digest from alg and a the hex encoded digest. +func NewDigestFromHex(alg, hex string) Digest { + return Digest(fmt.Sprintf("%s:%s", alg, hex)) +} + // DigestRegexp matches valid digest types. var DigestRegexp = regexp.MustCompile(`[a-zA-Z0-9-_+.]+:[a-zA-Z0-9-_+.=]+`) @@ -57,33 +62,24 @@ func ParseDigest(s string) (Digest, error) { // FromReader returns the most valid digest for the underlying content. func FromReader(rd io.Reader) (Digest, error) { - - // TODO(stevvooe): This is pretty inefficient to always be calculating a - // sha256 hash to provide fallback, but it provides some nice semantics in - // that we never worry about getting the right digest for a given reader. - // For the most part, we can detect tar vs non-tar with only a few bytes, - // so a scheme that saves those bytes would probably be better here. - h := sha256.New() - tr := io.TeeReader(rd, h) - ts, err := tarsum.NewTarSum(tr, true, tarsum.Version1) + if _, err := io.Copy(h, rd); err != nil { + return "", err + } + + return NewDigest("sha256", h), nil +} + +// FromTarArchive produces a tarsum digest from reader rd. +func FromTarArchive(rd io.Reader) (Digest, error) { + ts, err := tarsum.NewTarSum(rd, true, tarsum.Version1) if err != nil { return "", err } - // Try to copy from the tarsum, if we fail, copy the remaining bytes into - // hash directly. if _, err := io.Copy(ioutil.Discard, ts); err != nil { - if err.Error() != "archive/tar: invalid tar header" { - return "", err - } - - if _, err := io.Copy(h, rd); err != nil { - return "", err - } - - return NewDigest("sha256", h), nil + return "", err } d, err := ParseDigest(ts.Sum(nil)) diff --git a/digest/verifiers_test.go b/digest/verifiers_test.go index 939a8c81..4f2ae5c0 100644 --- a/digest/verifiers_test.go +++ b/digest/verifiers_test.go @@ -30,7 +30,7 @@ func TestDigestVerifier(t *testing.T) { t.Fatalf("error creating tarfile: %v", err) } - digest, err = FromReader(tf) + digest, err = FromTarArchive(tf) if err != nil { t.Fatalf("error digesting tarsum: %v", err) }