From cce0ab64e749b0c6f7f28feea3c7d55e44c3fc4a 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.go | 34 +++++++++++++++------------------- verifiers_test.go | 2 +- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/digest.go b/digest.go index a5d5b5a..40f1db1 100644 --- a/digest.go +++ b/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) { + h := sha256.New() - // 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. + if _, err := io.Copy(h, rd); err != nil { + return "", err + } - h := sha256.New() - tr := io.TeeReader(rd, h) + return NewDigest("sha256", h), nil +} - ts, err := tarsum.NewTarSum(tr, true, tarsum.Version1) +// 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/verifiers_test.go b/verifiers_test.go index 939a8c8..4f2ae5c 100644 --- a/verifiers_test.go +++ b/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) }