1
0
mirror of https://github.com/regclient/regclient.git synced 2025-04-17 11:37:11 +03:00

Feat: Improve fallback tag handling

The fallback tag should handle long digest algorithms, and should not output invalid tag characters.

Signed-off-by: Brandon Mitchell <git@bmitch.net>
This commit is contained in:
Brandon Mitchell 2025-03-19 14:59:21 -04:00
parent 4b212e6273
commit 6f656a37ba
No known key found for this signature in database
GPG Key ID: 6E0FF28C767A8BEE
2 changed files with 80 additions and 8 deletions

View File

@ -4,6 +4,7 @@ package referrer
import (
"bytes"
"fmt"
"regexp"
"slices"
"sort"
"text/tabwriter"
@ -151,12 +152,9 @@ func FallbackTag(r ref.Ref) (ref.Ref, error) {
if err != nil {
return r, fmt.Errorf("failed to parse digest for referrers: %w", err)
}
rr := r.SetTag(fmt.Sprintf("%s-%s", dig.Algorithm(), stringMax(dig.Hex(), 64)))
return rr, nil
}
func stringMax(s string, max int) string {
if len(s) <= max {
return s
}
return s[:max]
replaceRE := regexp.MustCompile(`[^a-zA-Z0-9._-]`)
algo := replaceRE.ReplaceAllString(string(dig.Algorithm()), "-")
hash := replaceRE.ReplaceAllString(string(dig.Hex()), "-")
rOut := r.SetTag(fmt.Sprintf("%.32s-%.64s", algo, hash))
return rOut, nil
}

View File

@ -2,6 +2,7 @@ package referrer
import (
"errors"
"fmt"
"strings"
"testing"
@ -362,6 +363,79 @@ func TestDelete(t *testing.T) {
}
}
func TestFallback(t *testing.T) {
t.Parallel()
dig256 := digest.SHA256.FromString("test")
dig512 := digest.SHA512.FromString("test")
digInvalid := "invalid+algorithm:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
fb256 := fmt.Sprintf("%s-%s", dig256.Algorithm(), dig256.Hex())
fb512 := fmt.Sprintf("%s-%.64s", dig512.Algorithm(), dig512.Hex())
rRef, err := ref.New("registry.example.org/proj")
if err != nil {
t.Fatalf("failed to set ref: %v", err)
}
oRef, err := ref.New("ocidir://path/to/proj")
if err != nil {
t.Fatalf("failed to set ref: %v", err)
}
tt := []struct {
name string
r ref.Ref
err error
expect ref.Ref
}{
{
name: "reg-sha256",
r: rRef.SetDigest(dig256.String()),
expect: rRef.SetTag(fb256),
},
{
name: "reg-sha512",
r: rRef.SetDigest(dig512.String()),
expect: rRef.SetTag(fb512),
},
{
name: "reg-invalid",
r: rRef.SetDigest(digInvalid),
err: digest.ErrDigestUnsupported,
},
{
name: "ocidir-sha256",
r: oRef.SetDigest(dig256.String()),
expect: oRef.SetTag(fb256),
},
{
name: "ocidir-sha512",
r: oRef.SetDigest(dig512.String()),
expect: oRef.SetTag(fb512),
},
{
name: "ocidir-invalid",
r: oRef.SetDigest(digInvalid),
err: digest.ErrDigestUnsupported,
},
}
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
out, err := FallbackTag(tc.r)
if tc.err != nil {
if err == nil {
t.Errorf("did not return expected error: %v", tc.err)
} else if !errors.Is(err, tc.err) {
t.Errorf("unexpected error, expected: %v, received: %v", tc.err, err)
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if out.CommonName() != tc.expect.CommonName() {
t.Errorf("expected %s, received %s", tc.expect.CommonName(), out.CommonName())
}
})
}
}
func TestMarshal(t *testing.T) {
t.Parallel()
rl := &ReferrerList{