From 74c32a0a51bfdc6c280dfc5fba3fa6e0a759bab2 Mon Sep 17 00:00:00 2001 From: Matt Moore Date: Wed, 7 Oct 2015 16:06:53 -0700 Subject: [PATCH] Allow hostname components in component names. Fixes https://github.com/docker/distribution/issues/1062 This relaxes the naming restrictions places on Docker images to permit valid hostnames according to [RFC-2396](https://www.ietf.org/rfc/rfc2396.txt). It deviates from the RFC in the following ways: 1) Allow underscores where we allow hyphens (hostnames don't allow underscores, which we must for backwards compatibility). 2) Leave "top-level" name segments unrestricted (domains require an alpha character to begin a top-level domain, e.g. "com"). 3) DO NOT allow a trailing dot, as permitted by FQDNs. Signed-off-by: Matt Moore --- registry/api/v2/names.go | 19 ++++++++++++--- registry/api/v2/names_test.go | 45 +++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/registry/api/v2/names.go b/registry/api/v2/names.go index 14b7ea60a..5f340793c 100644 --- a/registry/api/v2/names.go +++ b/registry/api/v2/names.go @@ -15,10 +15,23 @@ const ( RepositoryNameTotalLengthMax = 255 ) +// domainLabelRegexp represents the following RFC-2396 BNF construct: +// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum +var domainLabelRegexp = regexp.MustCompile(`[a-z0-9](?:-*[a-z0-9])*`) + // RepositoryNameComponentRegexp 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. -var RepositoryNameComponentRegexp = regexp.MustCompile(`[a-z0-9]+(?:[._-][a-z0-9]+)*`) +// the allow valid hostnames according to: https://www.ietf.org/rfc/rfc2396.txt +// with the following differences: +// 1) It DOES NOT allow for fully-qualified domain names, which include a +// trailing '.', e.g. "google.com." +// 2) It DOES NOT restrict 'top-level' domain labels to start with just alpha +// characters. +// 3) It DOES allow for underscores to appear in the same situations as dots. +// +// RFC-2396 uses the BNF construct: +// hostname = *( domainlabel "." ) toplabel [ "." ] +var RepositoryNameComponentRegexp = regexp.MustCompile( + domainLabelRegexp.String() + `(?:[._]` + domainLabelRegexp.String() + `)*`) // RepositoryNameComponentAnchoredRegexp is the version of // RepositoryNameComponentRegexp which must completely match the content diff --git a/registry/api/v2/names_test.go b/registry/api/v2/names_test.go index 656ae8466..f4daf2e7f 100644 --- a/registry/api/v2/names_test.go +++ b/registry/api/v2/names_test.go @@ -164,22 +164,47 @@ var ( err: ErrRepositoryNameComponentInvalid, invalid: true, }, + { + input: "do__cker/docker", + err: ErrRepositoryNameComponentInvalid, + invalid: true, + }, + { + input: "docker./docker", + err: ErrRepositoryNameComponentInvalid, + invalid: true, + }, + { + input: ".docker/docker", + err: ErrRepositoryNameComponentInvalid, + invalid: true, + }, + { + input: "do..cker/docker", + err: ErrRepositoryNameComponentInvalid, + invalid: true, + }, + { + input: "docker-/docker", + err: ErrRepositoryNameComponentInvalid, + invalid: true, + }, + { + input: "-docker/docker", + err: ErrRepositoryNameComponentInvalid, + invalid: true, + }, { input: "b.gcr.io/test.example.com/my-app", // embedded domain component }, - // TODO(stevvooe): The following is a punycode domain name that we may - // want to allow in the future. Currently, this is not allowed but we - // may want to change this in the future. Adding this here as invalid - // for the time being. { - input: "xn--n3h.com/myimage", // http://☃.com in punycode - err: ErrRepositoryNameComponentInvalid, - invalid: true, + input: "xn--n3h.com/myimage", // http://☃.com in punycode }, { - input: "xn--7o8h.com/myimage", // http://🐳.com in punycode - err: ErrRepositoryNameComponentInvalid, - invalid: true, + input: "xn--7o8h.com/myimage", // http://🐳.com in punycode + }, + { + input: "registry.io/foo/project--id.module--name.ver---sion--name", // image with hostname }, } )