Skip to content

Commit

Permalink
Merge pull request #33 from stevvooe/future-proof-algorithm-field
Browse files Browse the repository at this point in the history
digest: allow separators in algorithm field
  • Loading branch information
dmcgowan committed May 10, 2017
2 parents aa2ec05 + 678a95e commit eaa6054
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 13 deletions.
8 changes: 8 additions & 0 deletions algorithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ func (a Algorithm) Hash() hash.Hash {
return algorithms[a].New()
}

// Encode encodes the raw bytes of a digest, typically from a hash.Hash, into
// the encoded portion of the digest.
func (a Algorithm) Encode(d []byte) string {
// TODO(stevvooe): Currently, all algorithms use a hex encoding. When we
// add support for back registration, we can modify this accordingly.
return fmt.Sprintf("%x", d)
}

// FromReader returns the digest of the reader using the algorithm.
func (a Algorithm) FromReader(rd io.Reader) (Digest, error) {
digester := a.Digester()
Expand Down
22 changes: 16 additions & 6 deletions digest.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,21 @@ func NewDigest(alg Algorithm, h hash.Hash) Digest {
// functions. This is also useful for rebuilding digests from binary
// serializations.
func NewDigestFromBytes(alg Algorithm, p []byte) Digest {
return Digest(fmt.Sprintf("%s:%x", alg, p))
return NewDigestFromEncoded(alg, alg.Encode(p))
}

// NewDigestFromHex returns a Digest from alg and a the hex encoded digest.
// NewDigestFromHex is deprecated. Please use NewDigestFromEncoded.
func NewDigestFromHex(alg, hex string) Digest {
return Digest(fmt.Sprintf("%s:%s", alg, hex))
return NewDigestFromEncoded(Algorithm(alg), hex)
}

// NewDigestFromEncoded returns a Digest from alg and the encoded digest.
func NewDigestFromEncoded(alg Algorithm, encoded string) Digest {
return Digest(fmt.Sprintf("%s:%s", alg, encoded))
}

// DigestRegexp matches valid digest types.
var DigestRegexp = regexp.MustCompile(`[a-zA-Z0-9-_+.]+:[a-fA-F0-9]+`)
var DigestRegexp = regexp.MustCompile(`[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+`)

// DigestRegexpAnchored matches valid digest types, anchored to the start and end of the match.
var DigestRegexpAnchored = regexp.MustCompile(`^` + DigestRegexp.String() + `$`)
Expand Down Expand Up @@ -133,12 +138,17 @@ func (d Digest) Verifier() Verifier {
}
}

// Hex returns the hex digest portion of the digest. This will panic if the
// Encoded returns the encoded portion of the digest. This will panic if the
// underlying digest is not in a valid format.
func (d Digest) Hex() string {
func (d Digest) Encoded() string {
return string(d[d.sepIndex()+1:])
}

// Hex is deprecated. Please use Digest.Encoded.
func (d Digest) Hex() string {
return d.Encoded()
}

func (d Digest) String() string {
return string(d)
}
Expand Down
38 changes: 31 additions & 7 deletions digest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ func TestParseDigest(t *testing.T) {
input string
err error
algorithm Algorithm
hex string
encoded string
}{
{
input: "sha256:e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b",
algorithm: "sha256",
hex: "e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b",
encoded: "e58fcf7418d4390dec8e8fb69d88c06ec07039d651fedd3aa72af9972e7d046b",
},
{
input: "sha384:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
algorithm: "sha384",
hex: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
},
{
// empty hex
Expand All @@ -53,7 +53,7 @@ func TestParseDigest(t *testing.T) {
{
// not hex
input: "sha256:d41d8cd98f00b204e9800m98ecf8427e",
err: ErrDigestInvalidFormat,
err: ErrDigestInvalidLength,
},
{
// too short
Expand All @@ -69,6 +69,30 @@ func TestParseDigest(t *testing.T) {
input: "foo:d41d8cd98f00b204e9800998ecf8427e",
err: ErrDigestUnsupported,
},
{
// repeated separators
input: "sha384__foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
err: ErrDigestInvalidFormat,
},
{
// ensure that we parse, but we don't have support for the algorithm
input: "sha384.foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
algorithm: "sha384.foo+bar",
encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
err: ErrDigestUnsupported,
},
{
input: "sha384_foo+bar:d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
algorithm: "sha384_foo+bar",
encoded: "d3fc7881460b7e22e3d172954463dddd7866d17597e7248453c48b3e9d26d9596bf9c4a9cf8072c9d5bad76e19af801d",
err: ErrDigestUnsupported,
},
{
input: "sha256+b64:LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
algorithm: "sha256+b64",
encoded: "LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564",
err: ErrDigestUnsupported,
},
} {
digest, err := Parse(testcase.input)
if err != testcase.err {
Expand All @@ -83,8 +107,8 @@ func TestParseDigest(t *testing.T) {
t.Fatalf("incorrect algorithm for parsed digest: %q != %q", digest.Algorithm(), testcase.algorithm)
}

if digest.Hex() != testcase.hex {
t.Fatalf("incorrect hex for parsed digest: %q != %q", digest.Hex(), testcase.hex)
if digest.Encoded() != testcase.encoded {
t.Fatalf("incorrect hex for parsed digest: %q != %q", digest.Encoded(), testcase.encoded)
}

// Parse string return value and check equality
Expand All @@ -98,7 +122,7 @@ func TestParseDigest(t *testing.T) {
t.Fatalf("expected equal: %q != %q", newParsed, digest)
}

newFromHex := NewDigestFromHex(newParsed.Algorithm().String(), newParsed.Hex())
newFromHex := NewDigestFromEncoded(newParsed.Algorithm(), newParsed.Encoded())
if newFromHex != digest {
t.Fatalf("%v != %v", newFromHex, digest)
}
Expand Down

0 comments on commit eaa6054

Please sign in to comment.