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)master
							parent
							
								
									bcda04d6cd
								
							
						
					
					
						commit
						6bd5b8c24e
					
				|  | @ -8,12 +8,13 @@ | |||
| //	// repository.go
 | ||||
| //	repository			:= hostname ['/' component]+
 | ||||
| //	hostname 			:= hostcomponent [':' port-number]
 | ||||
| //	component			:= alpha-numeric [separator alpha-numeric]*
 | ||||
| //	component			:= subcomponent [separator subcomponent]*
 | ||||
| //	subcomponent			:= alpha-numeric ['-'* alpha-numeric]*
 | ||||
| //	hostcomponent                   := [hostpart '.']* hostpart
 | ||||
| // 	alpha-numeric			:= /[a-zA-Z0-9]+/
 | ||||
| //	separator			:= /[_-]/
 | ||||
| // 	alpha-numeric			:= /[a-z0-9]+/
 | ||||
| //	separator			:= /([_.]|__)/
 | ||||
| //	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                             := /[\w][\w.-]{0,127}/
 | ||||
|  |  | |||
|  | @ -3,14 +3,19 @@ package reference | |||
| import "regexp" | ||||
| 
 | ||||
| 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
 | ||||
| 	// start with at least one letter or number, with following parts able to
 | ||||
| 	// be separated by one period, dash or underscore.
 | ||||
| 	nameComponentRegexp = regexp.MustCompile(`[a-zA-Z0-9]+(?:[._-][a-z0-9]+)*`) | ||||
| 	// be separated by one period, underscore or double underscore.
 | ||||
| 	nameComponentRegexp = regexp.MustCompile(nameSubComponentRegexp.String() + `(?:(?:[._]|__)` + nameSubComponentRegexp.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
 | ||||
| 	// 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) | ||||
| 	if m.match && matches != nil { | ||||
| 		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) { | ||||
| 			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 { | ||||
| 			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 { | ||||
|  | @ -325,6 +325,75 @@ func TestFullNameRegexp(t *testing.T) { | |||
| 			match: true, | ||||
| 			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 { | ||||
| 		checkRegexp(t, anchoredNameRegexp, testcases[i]) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue