commit
						b09de5e105
					
				|  | @ -72,6 +72,10 @@ func (a *Algorithm) Set(value string) error { | ||||||
| 		*a = Algorithm(value) | 		*a = Algorithm(value) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if !a.Available() { | ||||||
|  | 		return ErrDigestUnsupported | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,100 @@ | ||||||
|  | package digest | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	_ "crypto/sha256" | ||||||
|  | 	_ "crypto/sha512" | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestFlagInterface(t *testing.T) { | ||||||
|  | 	var ( | ||||||
|  | 		alg     Algorithm | ||||||
|  | 		flagSet flag.FlagSet | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	flagSet.Var(&alg, "algorithm", "set the digest algorithm") | ||||||
|  | 	for _, testcase := range []struct { | ||||||
|  | 		Name     string | ||||||
|  | 		Args     []string | ||||||
|  | 		Err      error | ||||||
|  | 		Expected Algorithm | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			Name: "Invalid", | ||||||
|  | 			Args: []string{"-algorithm", "bean"}, | ||||||
|  | 			Err:  ErrDigestUnsupported, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			Name:     "Default", | ||||||
|  | 			Args:     []string{"unrelated"}, | ||||||
|  | 			Expected: "sha256", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			Name:     "Other", | ||||||
|  | 			Args:     []string{"-algorithm", "sha512"}, | ||||||
|  | 			Expected: "sha512", | ||||||
|  | 		}, | ||||||
|  | 	} { | ||||||
|  | 		t.Run(testcase.Name, func(t *testing.T) { | ||||||
|  | 			alg = 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 alg != testcase.Expected { | ||||||
|  | 				t.Fatalf("unexpected algorithm: %v != %v", alg, testcase.Expected) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestFroms(t *testing.T) { | ||||||
|  | 	p := make([]byte, 1<<20) | ||||||
|  | 	rand.Read(p) | ||||||
|  | 
 | ||||||
|  | 	for alg := range algorithms { | ||||||
|  | 		h := alg.Hash() | ||||||
|  | 		h.Write(p) | ||||||
|  | 		expected := Digest(fmt.Sprintf("%s:%x", alg, h.Sum(nil))) | ||||||
|  | 		readerDgst, err := alg.FromReader(bytes.NewReader(p)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("error calculating hash from reader: %v", err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		dgsts := []Digest{ | ||||||
|  | 			alg.FromBytes(p), | ||||||
|  | 			alg.FromString(string(p)), | ||||||
|  | 			readerDgst, | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if alg == Canonical { | ||||||
|  | 			readerDgst, err := FromReader(bytes.NewReader(p)) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("error calculating hash from reader: %v", err) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			dgsts = append(dgsts, | ||||||
|  | 				FromBytes(p), | ||||||
|  | 				FromString(string(p)), | ||||||
|  | 				readerDgst) | ||||||
|  | 		} | ||||||
|  | 		for _, dgst := range dgsts { | ||||||
|  | 			if dgst != expected { | ||||||
|  | 				t.Fatalf("unexpected digest %v != %v", dgst, expected) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -94,17 +94,10 @@ func FromString(s string) Digest { | ||||||
| func (d Digest) Validate() error { | func (d Digest) Validate() error { | ||||||
| 	s := string(d) | 	s := string(d) | ||||||
| 
 | 
 | ||||||
| 	if !DigestRegexpAnchored.MatchString(s) { |  | ||||||
| 		return ErrDigestInvalidFormat |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	i := strings.Index(s, ":") | 	i := strings.Index(s, ":") | ||||||
| 	if i < 0 { |  | ||||||
| 		return ErrDigestInvalidFormat |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// case: "sha256:" with no hex.
 | 	// validate i then run through regexp
 | ||||||
| 	if i+1 == len(s) { | 	if i < 0 || i+1 == len(s) || !DigestRegexpAnchored.MatchString(s) { | ||||||
| 		return ErrDigestInvalidFormat | 		return ErrDigestInvalidFormat | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| package digest | package digest | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	_ "crypto/sha256" |  | ||||||
| 	_ "crypto/sha512" |  | ||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -28,6 +26,11 @@ func TestParseDigest(t *testing.T) { | ||||||
| 			input: "sha256:", | 			input: "sha256:", | ||||||
| 			err:   ErrDigestInvalidFormat, | 			err:   ErrDigestInvalidFormat, | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			// empty hex
 | ||||||
|  | 			input: ":", | ||||||
|  | 			err:   ErrDigestInvalidFormat, | ||||||
|  | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			// just hex
 | 			// just hex
 | ||||||
| 			input: "d41d8cd98f00b204e9800998ecf8427e", | 			input: "d41d8cd98f00b204e9800998ecf8427e", | ||||||
|  | @ -80,5 +83,10 @@ func TestParseDigest(t *testing.T) { | ||||||
| 		if newParsed != digest { | 		if newParsed != digest { | ||||||
| 			t.Fatalf("expected equal: %q != %q", newParsed, digest) | 			t.Fatalf("expected equal: %q != %q", newParsed, digest) | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		newFromHex := NewDigestFromHex(newParsed.Algorithm().String(), newParsed.Hex()) | ||||||
|  | 		if newFromHex != digest { | ||||||
|  | 			t.Fatalf("%v != %v", newFromHex, digest) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue