Skip to content

Commit

Permalink
Exclude domain from name length check
Browse files Browse the repository at this point in the history
Signed-off-by: Ozair <ozair.asim@docker.com>
  • Loading branch information
ozairasim committed Feb 14, 2024
1 parent 8507c7f commit aaca75e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
28 changes: 17 additions & 11 deletions reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@ import (
)

const (
// RepositoryNameTotalLengthMax is the maximum total number of characters in a repository name.
RepositoryNameTotalLengthMax = 255

// NameTotalLengthMax is the maximum total number of characters in a repository name.
NameTotalLengthMax = 255
//
// Deprecated: use [RepositoryNameTotalLengthMax] instead.
NameTotalLengthMax = RepositoryNameTotalLengthMax
)

var (
Expand All @@ -55,8 +60,8 @@ var (
// ErrNameEmpty is returned for empty, invalid repository names.
ErrNameEmpty = errors.New("repository name must have at least one component")

// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", NameTotalLengthMax)
// ErrNameTooLong is returned when a repository name is longer than RepositoryNameTotalLengthMax.
ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", RepositoryNameTotalLengthMax)

// ErrNameNotCanonical is returned when a name is not canonical.
ErrNameNotCanonical = errors.New("repository name must be canonical")
Expand Down Expand Up @@ -190,10 +195,6 @@ func Parse(s string) (Reference, error) {
return nil, ErrReferenceInvalidFormat
}

if len(matches[1]) > NameTotalLengthMax {
return nil, ErrNameTooLong
}

var repo repository

nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
Expand All @@ -205,6 +206,10 @@ func Parse(s string) (Reference, error) {
repo.path = matches[1]
}

if len(repo.path) > RepositoryNameTotalLengthMax {
return nil, ErrNameTooLong
}

ref := reference{
namedRepository: repo,
tag: matches[2],
Expand Down Expand Up @@ -243,14 +248,15 @@ func ParseNamed(s string) (Named, error) {
// WithName returns a named object representing the given string. If the input
// is invalid ErrReferenceInvalidFormat will be returned.
func WithName(name string) (Named, error) {
if len(name) > NameTotalLengthMax {
return nil, ErrNameTooLong
}

match := anchoredNameRegexp.FindStringSubmatch(name)
if match == nil || len(match) != 3 {
return nil, ErrReferenceInvalidFormat
}

if len(match[2]) > RepositoryNameTotalLengthMax {
return nil, ErrNameTooLong
}

return repository{
domain: match[1],
path: match[2],
Expand Down
21 changes: 16 additions & 5 deletions reference_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
_ "crypto/sha256"
_ "crypto/sha512"
"encoding/json"
"errors"
"strings"
"testing"

Expand Down Expand Up @@ -117,7 +118,7 @@ func TestReferenceParse(t *testing.T) {
tag: "Uppercase",
},
{
input: strings.Repeat("a/", 128) + "a:tag",
input: "domain/" + strings.Repeat("a", 256) + ":tag",
err: ErrNameTooLong,
},
{
Expand Down Expand Up @@ -266,6 +267,12 @@ func TestReferenceParse(t *testing.T) {
input: "[fe80::1%@invalidzone]:5000/repo",
err: ErrReferenceInvalidFormat,
},
{
input: "example.com/" + strings.Repeat("a", 255) + ":tag",
domain: "example.com",
repository: "example.com/" + strings.Repeat("a", 255),
tag: "tag",
},
}
for _, tc := range tests {
tc := tc
Expand Down Expand Up @@ -337,7 +344,7 @@ func TestWithNameFailure(t *testing.T) {
}{
{
input: "",
err: ErrNameEmpty,
err: ErrReferenceInvalidFormat,
},
{
input: ":justtag",
Expand All @@ -352,7 +359,11 @@ func TestWithNameFailure(t *testing.T) {
err: ErrReferenceInvalidFormat,
},
{
input: strings.Repeat("a/", 128) + "a:tag",
input: "example.com/repo:tag",
err: ErrReferenceInvalidFormat,
},
{
input: "example.com/" + strings.Repeat("a", 256),
err: ErrNameTooLong,
},
{
Expand All @@ -365,8 +376,8 @@ func TestWithNameFailure(t *testing.T) {
t.Run(tc.input, func(t *testing.T) {
t.Parallel()
_, err := WithName(tc.input)
if err == nil {
t.Errorf("no error parsing name. expected: %s", tc.err)
if !errors.Is(err, tc.err) {
t.Errorf("unexpected error parsing name. expected: %s, got: %s", tc.err, err)
}
})
}
Expand Down

0 comments on commit aaca75e

Please sign in to comment.