forked from TrueCloudLab/distribution
Update regexp to support repeated dash and double underscore
In order to support valid hostnames as name components, supporting repeated dash was added. Additionally double underscore is now allowed as a separator to loosen the restriction for previously supported names. Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
parent
bcda04d6cd
commit
6bd5b8c24e
3 changed files with 85 additions and 10 deletions
|
@ -8,12 +8,13 @@
|
||||||
// // repository.go
|
// // repository.go
|
||||||
// repository := hostname ['/' component]+
|
// repository := hostname ['/' component]+
|
||||||
// hostname := hostcomponent [':' port-number]
|
// hostname := hostcomponent [':' port-number]
|
||||||
// component := alpha-numeric [separator alpha-numeric]*
|
// component := subcomponent [separator subcomponent]*
|
||||||
|
// subcomponent := alpha-numeric ['-'* alpha-numeric]*
|
||||||
// hostcomponent := [hostpart '.']* hostpart
|
// hostcomponent := [hostpart '.']* hostpart
|
||||||
// alpha-numeric := /[a-zA-Z0-9]+/
|
// alpha-numeric := /[a-z0-9]+/
|
||||||
// separator := /[_-]/
|
// separator := /([_.]|__)/
|
||||||
// port-number := /[0-9]+/
|
// port-number := /[0-9]+/
|
||||||
// hostpart := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
|
// hostpart := /([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])/
|
||||||
//
|
//
|
||||||
// // tag.go
|
// // tag.go
|
||||||
// tag := /[\w][\w.-]{0,127}/
|
// tag := /[\w][\w.-]{0,127}/
|
||||||
|
|
|
@ -3,14 +3,19 @@ package reference
|
||||||
import "regexp"
|
import "regexp"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// nameSubComponentRegexp defines the part of the name which must be
|
||||||
|
// begin and end with an alphanumeric character. These characters can
|
||||||
|
// be separated by any number of dashes.
|
||||||
|
nameSubComponentRegexp = regexp.MustCompile(`[a-z0-9]+(?:[-]+[a-z0-9]+)*`)
|
||||||
|
|
||||||
// nameComponentRegexp restricts registry path component names to
|
// nameComponentRegexp restricts registry path component names to
|
||||||
// start with at least one letter or number, with following parts able to
|
// start with at least one letter or number, with following parts able to
|
||||||
// be separated by one period, dash or underscore.
|
// be separated by one period, underscore or double underscore.
|
||||||
nameComponentRegexp = regexp.MustCompile(`[a-zA-Z0-9]+(?:[._-][a-z0-9]+)*`)
|
nameComponentRegexp = regexp.MustCompile(nameSubComponentRegexp.String() + `(?:(?:[._]|__)` + nameSubComponentRegexp.String() + `)*`)
|
||||||
|
|
||||||
nameRegexp = regexp.MustCompile(`(?:` + nameComponentRegexp.String() + `/)*` + nameComponentRegexp.String())
|
nameRegexp = regexp.MustCompile(`(?:` + nameComponentRegexp.String() + `/)*` + nameComponentRegexp.String())
|
||||||
|
|
||||||
hostnameComponentRegexp = regexp.MustCompile(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
|
hostnameComponentRegexp = regexp.MustCompile(`(?:[a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])`)
|
||||||
|
|
||||||
// hostnameComponentRegexp restricts the registry hostname component of a repository name to
|
// hostnameComponentRegexp restricts the registry hostname component of a repository name to
|
||||||
// start with a component as defined by hostnameRegexp and followed by an optional port.
|
// start with a component as defined by hostnameRegexp and followed by an optional port.
|
||||||
|
|
|
@ -16,14 +16,14 @@ func checkRegexp(t *testing.T, r *regexp.Regexp, m regexpMatch) {
|
||||||
matches := r.FindStringSubmatch(m.input)
|
matches := r.FindStringSubmatch(m.input)
|
||||||
if m.match && matches != nil {
|
if m.match && matches != nil {
|
||||||
if len(matches) != (r.NumSubexp()+1) || matches[0] != m.input {
|
if len(matches) != (r.NumSubexp()+1) || matches[0] != m.input {
|
||||||
t.Fatalf("Bad match result: %#v", matches)
|
t.Fatalf("Bad match result %#v for %q", matches, m.input)
|
||||||
}
|
}
|
||||||
if len(matches) < (len(m.subs) + 1) {
|
if len(matches) < (len(m.subs) + 1) {
|
||||||
t.Errorf("Expected %d sub matches, only have %d", len(m.subs), len(matches)-1)
|
t.Errorf("Expected %d sub matches, only have %d for %q", len(m.subs), len(matches)-1, m.input)
|
||||||
}
|
}
|
||||||
for i := range m.subs {
|
for i := range m.subs {
|
||||||
if m.subs[i] != matches[i+1] {
|
if m.subs[i] != matches[i+1] {
|
||||||
t.Errorf("Unexpected submatch %d: %q, expected %q", i+1, matches[i+1], m.subs[i])
|
t.Errorf("Unexpected submatch %d: %q, expected %q for %q", i+1, matches[i+1], m.subs[i], m.input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if m.match {
|
} else if m.match {
|
||||||
|
@ -325,6 +325,75 @@ func TestFullNameRegexp(t *testing.T) {
|
||||||
match: true,
|
match: true,
|
||||||
subs: []string{"xn--7o8h.com", "myimage"},
|
subs: []string{"xn--7o8h.com", "myimage"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: "example.com/xn--7o8h.com/myimage", // 🐳.com in punycode
|
||||||
|
match: true,
|
||||||
|
subs: []string{"example.com", "xn--7o8h.com/myimage"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "example.com/some_separator__underscore/myimage",
|
||||||
|
match: true,
|
||||||
|
subs: []string{"example.com", "some_separator__underscore/myimage"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "example.com/__underscore/myimage",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "example.com/..dots/myimage",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "example.com/.dots/myimage",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "example.com/nodouble..dots/myimage",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "example.com/nodouble..dots/myimage",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "docker./docker",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: ".docker/docker",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "docker-/docker",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "-docker/docker",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "do..cker/docker",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "do__cker:8080/docker",
|
||||||
|
match: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "do__cker/docker",
|
||||||
|
match: true,
|
||||||
|
subs: []string{"", "do__cker/docker"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "b.gcr.io/test.example.com/my-app",
|
||||||
|
match: true,
|
||||||
|
subs: []string{"b.gcr.io", "test.example.com/my-app"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "registry.io/foo/project--id.module--name.ver---sion--name",
|
||||||
|
match: true,
|
||||||
|
subs: []string{"registry.io", "foo/project--id.module--name.ver---sion--name"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for i := range testcases {
|
for i := range testcases {
|
||||||
checkRegexp(t, anchoredNameRegexp, testcases[i])
|
checkRegexp(t, anchoredNameRegexp, testcases[i])
|
||||||
|
|
Loading…
Reference in a new issue