forked from opencontainers/go-digest
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
*: Replace implicit hex hash encoding with Algorithm-based encoding
The docs for 'Algorithm' (now 'algorithm') made it clear that the algorithm identifier was intended to cover both the hash and encoding algorithms. Stephen confirmed this interpretation in recent comments [1,2] as well. The idea is that a future algorithm may chose a non-hex encoding like base 64 [1]. The previous implementation, on the other hand, baked the hex encoding into key locations (e.g. in NewDigestFromBytes and Digest.Validate). This commit makes the encoding internal to Agorithm instances, adding a new Encoding interface and an Algorithm.Encoding method. In order support external algorithms with different encoding, I've defined an Algorithm interface with the public API and made renamed the local implementation of that interface to 'algorithm'. And now that Algorithm is a stand-alone interface, I've made the identifier-to-Algorithm registry public by renaming 'algorithms' to 'Algorithm'. I've also split out the flag binding into its own AlgorithmFlag structure, because the old Algorithm.Set pointer assignment no longer works now that Algorithm is an interface. Having a separate interface for the flag.Value also simplifies the Algorithm interface, which makes it easier to write external Algorithm implementations while still benefiting from the flag.Value helper. API changes: * Additions * Algorithms, a newly-public registry of known algorithm identifiers. * Algorithm.HashSize, which allows us to avoid a previously-hardcoded hex assumption in Digest.Validate(). * Algorithm.Encoding, which allows us to implement NewDigester and avoid a previously-hardcoded hex assumption in NewDigestFromBytes. * Digest.Hash, as a better name for Digest.Hex. * Encoding, a new interface backing Algorithm.Encoding. * Hex, the lowercase base 16 Encoding. * NewDigester, as a more flexible replacement for NewDigest. * NewDigestFromHash, as a better name for NewDigestFromHex. * Adjustments * Algorithm.Hash now returns nil on unavailable algorithms, to mirror the old API for Algorithm.Digester. * Deprecations * NewDigest, because NewDigester is a more flexible form of the same thing that is just about as compact. * NewDigestFromHex, because NewDigestFromHash is a better name for this function. * Digest.Hex, because Hash is a better name for this method. * Removals * Algorithm.Set, because it is not possible to support this now that Algorithm is an interface. I also switched to black-box testing (with digest_test package names) because I was getting Hex-undefined errors with white-box testing, and we don't actually need any white-box access in our test suite. [1]: opencontainers#3 (comment) [2]: opencontainers#6 (comment) Signed-off-by: W. Trevor King <wking@tremily.us>
- Loading branch information
Showing
12 changed files
with
442 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2017 go-digest contributors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package digest | ||
|
||
type AlgorithmFlag struct { | ||
Algorithm Algorithm | ||
} | ||
|
||
// String implements the flag.Value interface for Algorithms. | ||
// https://golang.org/pkg/flag/#Value | ||
func (flag *AlgorithmFlag) String() string { | ||
if flag.Algorithm == nil { | ||
return "unset" | ||
} | ||
return flag.Algorithm.String() | ||
} | ||
|
||
// Set implements the flag.Value interface for Algorithms. | ||
// https://golang.org/pkg/flag/#Value | ||
func (flag *AlgorithmFlag) Set(value string) error { | ||
if value == "" { | ||
flag.Algorithm = Canonical | ||
} else { | ||
alg, ok := Algorithms[value] | ||
if !ok || !alg.Available() { | ||
return ErrDigestUnsupported | ||
} | ||
|
||
flag.Algorithm = alg | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2017 go-digest contributors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package digest_test | ||
|
||
import ( | ||
_ "crypto/sha256" | ||
_ "crypto/sha512" | ||
"flag" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/opencontainers/go-digest" | ||
) | ||
|
||
func TestFlagInterface(t *testing.T) { | ||
var ( | ||
algFlag digest.AlgorithmFlag | ||
flagSet flag.FlagSet | ||
) | ||
|
||
flagSet.Var(&algFlag, "algorithm", "set the digest algorithm") | ||
for _, testcase := range []struct { | ||
Name string | ||
Args []string | ||
Err error | ||
Expected digest.Algorithm | ||
}{ | ||
{ | ||
Name: "Invalid", | ||
Args: []string{"-algorithm", "bean"}, | ||
Err: digest.ErrDigestUnsupported, | ||
}, | ||
{ | ||
Name: "Default", | ||
Args: []string{"unrelated"}, | ||
Expected: digest.SHA256, | ||
}, | ||
{ | ||
Name: "Other", | ||
Args: []string{"-algorithm", "sha512"}, | ||
Expected: digest.SHA512, | ||
}, | ||
} { | ||
t.Run(testcase.Name, func(t *testing.T) { | ||
algFlag = digest.AlgorithmFlag{ | ||
Algorithm: digest.Canonical, | ||
} | ||
if err := flagSet.Parse(testcase.Args); err != testcase.Err { | ||
if testcase.Err == nil { | ||
t.Fatal("unexpected error", err) | ||
} | ||
|
||
// check that flag package returns correct error | ||
if !strings.Contains(err.Error(), testcase.Err.Error()) { | ||
t.Fatalf("unexpected error: %v != %v", err, testcase.Err) | ||
} | ||
return | ||
} | ||
|
||
if algFlag.Algorithm != testcase.Expected { | ||
t.Fatalf("unexpected algorithm: %v != %v", algFlag.Algorithm, testcase.Expected) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.