identifiers: adjust requirements for identifiers
Based on feedback, a few adjustments have been made to the identifier requirements. Identifiers that have components that start with a number are now allowed. This violates RFC 1035 but does not do so for dns names practically. A total length, of 76 characters is now also enforced. This decision was completely arbitrary but satifies the requirement for a maximum length. Often, this is used as the maximum length of a line in editors, so it should be a good choice. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
parent
a5fa3bb923
commit
0e34531c58
@ -6,8 +6,12 @@
|
|||||||
// 2.3.1. This will make identifiers safe for use across networks, filesystems
|
// 2.3.1. This will make identifiers safe for use across networks, filesystems
|
||||||
// and other media.
|
// and other media.
|
||||||
//
|
//
|
||||||
// While the character set may expand in the future, we guarantee that the
|
// The identifier specification departs from RFC 1035 in that it allows
|
||||||
// identifiers will be safe for use as filesystem path components.
|
// "labels" to start with number and only enforces a total length restriction
|
||||||
|
// of 76 characters.
|
||||||
|
//
|
||||||
|
// While the character set may be expanded in the future, identifiers are
|
||||||
|
// guaranteed to be safely used as filesystem path components.
|
||||||
package identifiers
|
package identifiers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -17,7 +21,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
label = `[A-Za-z][A-Za-z0-9]+(?:[-]+[A-Za-z0-9]+)*`
|
maxLength = 76
|
||||||
|
charclass = `[A-Za-z0-9]+`
|
||||||
|
label = charclass + `(:?[-]+` + charclass + `)*`
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -27,7 +33,7 @@ var (
|
|||||||
// identifiers.
|
// identifiers.
|
||||||
identifierRe = regexp.MustCompile(reAnchor(label + reGroup("[.]"+reGroup(label)) + "*"))
|
identifierRe = regexp.MustCompile(reAnchor(label + reGroup("[.]"+reGroup(label)) + "*"))
|
||||||
|
|
||||||
errIdentifierInvalid = errors.Errorf("invalid, must match %v", identifierRe)
|
errIdentifierInvalid = errors.New("invalid identifier")
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsInvalid return true if the error was due to an invalid identifer.
|
// IsInvalid return true if the error was due to an invalid identifer.
|
||||||
@ -43,8 +49,12 @@ func IsInvalid(err error) bool {
|
|||||||
// In general, identifiers that pass this validation, should be safe for use as
|
// In general, identifiers that pass this validation, should be safe for use as
|
||||||
// a domain identifier or filesystem path component.
|
// a domain identifier or filesystem path component.
|
||||||
func Validate(s string) error {
|
func Validate(s string) error {
|
||||||
|
if len(s) > maxLength {
|
||||||
|
return errors.Wrapf(errIdentifierInvalid, "identifier %q greater than maximum length (%d characters)", s, maxLength)
|
||||||
|
}
|
||||||
|
|
||||||
if !identifierRe.MatchString(s) {
|
if !identifierRe.MatchString(s) {
|
||||||
return errors.Wrapf(errIdentifierInvalid, "identifier %q", s)
|
return errors.Wrapf(errIdentifierInvalid, "identifier %q must match %v", s, identifierRe)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package identifiers
|
package identifiers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,6 +16,9 @@ func TestValidIdentifiers(t *testing.T) {
|
|||||||
"foo.boo",
|
"foo.boo",
|
||||||
"swarmkit.docker.io",
|
"swarmkit.docker.io",
|
||||||
"zn--e9.org", // or something like it!
|
"zn--e9.org", // or something like it!
|
||||||
|
"0912341234",
|
||||||
|
"task.0.0123456789",
|
||||||
|
strings.Repeat("a", maxLength),
|
||||||
} {
|
} {
|
||||||
t.Run(input, func(t *testing.T) {
|
t.Run(input, func(t *testing.T) {
|
||||||
if err := Validate(input); err != nil {
|
if err := Validate(input); err != nil {
|
||||||
@ -34,6 +38,7 @@ func TestInvalidIdentifiers(t *testing.T) {
|
|||||||
"-foo.boo",
|
"-foo.boo",
|
||||||
"foo.boo-",
|
"foo.boo-",
|
||||||
"foo_foo.boo_underscores", // boo-urns?
|
"foo_foo.boo_underscores", // boo-urns?
|
||||||
|
strings.Repeat("a", maxLength+1),
|
||||||
} {
|
} {
|
||||||
|
|
||||||
t.Run(input, func(t *testing.T) {
|
t.Run(input, func(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user