Ver código fonte

Allow uppercase characters in image reference hostname

This PR makes restores the pre-Docker 1.10 behavior of allowing
uppercase characters in registry hostnames.

Note that this only applies to hostnames, not remote image names.
Previous versions also prohibited uppercase letters after the hostname,
but Docker 1.10 extended this to the hostname itself.

- Vendor updated distribution docker/1.10 branch.

- Add a check to "normalize" that rejects remote names with uppercase
  letters.

- Add test cases to TestTagValidPrefixedRepo and
  TestTagInvalidUnprefixedRepo

Fixes: #20056

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Aaron Lehmann 9 anos atrás
pai
commit
f38610df1f

+ 1 - 1
hack/vendor.sh

@@ -46,7 +46,7 @@ clone git github.com/boltdb/bolt v1.1.0
 clone git github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
 clone git github.com/miekg/dns 75e6e86cc601825c5dbcd4e0c209eab180997cd7
 
 
 # get graph and distribution packages
 # get graph and distribution packages
-clone git github.com/docker/distribution c301f8ab27f4913c968b8d73a38e5dda79b9d3d7
+clone git github.com/docker/distribution 0f2d99b13ae0cfbcf118eff103e6e680b726b47e
 clone git github.com/vbatts/tar-split v0.9.11
 clone git github.com/vbatts/tar-split v0.9.11
 
 
 # get desired notary commit, might also need to be updated in Dockerfile
 # get desired notary commit, might also need to be updated in Dockerfile

+ 2 - 2
integration-cli/docker_cli_tag_test.go

@@ -30,7 +30,7 @@ func (s *DockerSuite) TestTagUnprefixedRepoByID(c *check.C) {
 
 
 // ensure we don't allow the use of invalid repository names; these tag operations should fail
 // ensure we don't allow the use of invalid repository names; these tag operations should fail
 func (s *DockerSuite) TestTagInvalidUnprefixedRepo(c *check.C) {
 func (s *DockerSuite) TestTagInvalidUnprefixedRepo(c *check.C) {
-	invalidRepos := []string{"fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo%asd"}
+	invalidRepos := []string{"fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo%asd", "FOO/bar"}
 
 
 	for _, repo := range invalidRepos {
 	for _, repo := range invalidRepos {
 		out, _, err := dockerCmdWithError("tag", "busybox", repo)
 		out, _, err := dockerCmdWithError("tag", "busybox", repo)
@@ -57,7 +57,7 @@ func (s *DockerSuite) TestTagValidPrefixedRepo(c *check.C) {
 		c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
 		c.Fatal("couldn't find the busybox:latest image locally and failed to pull it")
 	}
 	}
 
 
-	validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t"}
+	validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t", "HOSTNAME.DOMAIN.COM:443/foo/bar"}
 
 
 	for _, repo := range validRepos {
 	for _, repo := range validRepos {
 		_, _, err := dockerCmdWithError("tag", "busybox:latest", repo)
 		_, _, err := dockerCmdWithError("tag", "busybox:latest", repo)

+ 12 - 5
reference/reference.go

@@ -1,6 +1,7 @@
 package reference
 package reference
 
 
 import (
 import (
+	"errors"
 	"fmt"
 	"fmt"
 	"strings"
 	"strings"
 
 
@@ -72,7 +73,10 @@ func ParseNamed(s string) (Named, error) {
 // WithName returns a named object representing the given string. If the input
 // WithName returns a named object representing the given string. If the input
 // is invalid ErrReferenceInvalidFormat will be returned.
 // is invalid ErrReferenceInvalidFormat will be returned.
 func WithName(name string) (Named, error) {
 func WithName(name string) (Named, error) {
-	name = normalize(name)
+	name, err := normalize(name)
+	if err != nil {
+		return nil, err
+	}
 	if err := validateName(name); err != nil {
 	if err := validateName(name); err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -172,15 +176,18 @@ func splitHostname(name string) (hostname, remoteName string) {
 
 
 // normalize returns a repository name in its normalized form, meaning it
 // normalize returns a repository name in its normalized form, meaning it
 // will not contain default hostname nor library/ prefix for official images.
 // will not contain default hostname nor library/ prefix for official images.
-func normalize(name string) string {
+func normalize(name string) (string, error) {
 	host, remoteName := splitHostname(name)
 	host, remoteName := splitHostname(name)
+	if strings.ToLower(remoteName) != remoteName {
+		return "", errors.New("invalid reference format: repository name must be lowercase")
+	}
 	if host == DefaultHostname {
 	if host == DefaultHostname {
 		if strings.HasPrefix(remoteName, DefaultRepoPrefix) {
 		if strings.HasPrefix(remoteName, DefaultRepoPrefix) {
-			return strings.TrimPrefix(remoteName, DefaultRepoPrefix)
+			return strings.TrimPrefix(remoteName, DefaultRepoPrefix), nil
 		}
 		}
-		return remoteName
+		return remoteName, nil
 	}
 	}
-	return name
+	return name, nil
 }
 }
 
 
 func validateName(name string) error {
 func validateName(name string) error {

+ 1 - 1
vendor/src/github.com/docker/distribution/reference/reference.go

@@ -6,7 +6,7 @@
 // 	reference                       := repository [ ":" tag ] [ "@" digest ]
 // 	reference                       := repository [ ":" tag ] [ "@" digest ]
 //	name                            := [hostname '/'] component ['/' component]*
 //	name                            := [hostname '/'] component ['/' component]*
 //	hostname                        := hostcomponent ['.' hostcomponent]* [':' port-number]
 //	hostname                        := hostcomponent ['.' hostcomponent]* [':' port-number]
-//	hostcomponent                   := /([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])/
+//	hostcomponent                   := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
 //	port-number                     := /[0-9]+/
 //	port-number                     := /[0-9]+/
 //	component                       := alpha-numeric [separator alpha-numeric]*
 //	component                       := alpha-numeric [separator alpha-numeric]*
 // 	alpha-numeric                   := /[a-z0-9]+/
 // 	alpha-numeric                   := /[a-z0-9]+/

+ 1 - 1
vendor/src/github.com/docker/distribution/reference/regexp.go

@@ -22,7 +22,7 @@ var (
 	// hostnameComponentRegexp restricts the registry hostname component of a
 	// hostnameComponentRegexp restricts the registry hostname component of a
 	// repository name to start with a component as defined by hostnameRegexp
 	// repository name to start with a component as defined by hostnameRegexp
 	// and followed by an optional port.
 	// and followed by an optional port.
-	hostnameComponentRegexp = match(`(?:[a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])`)
+	hostnameComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
 
 
 	// hostnameRegexp defines the structure of potential hostname components
 	// hostnameRegexp defines the structure of potential hostname components
 	// that may be part of image names. This is purposely a subset of what is
 	// that may be part of image names. This is purposely a subset of what is