mirror of https://github.com/docker/cli.git
cli/context/store: replace restrictedNamePattern for isValidName utility
The restrictedNamePattern was a basic regular expression. Replace it
with a minimal utility to do the same, without having to use regular
expressions (or the "lazyregexp" package).
Some quick benchmarking (not committed) show that the non-regex approach
is ~18x faster:
BenchmarkIsValidName_Regex_Valid-10 8516511 119.4 ns/op 0 B/op 0 allocs/op
BenchmarkIsValidName_Manual_Valid-10 172426240 6.964 ns/op 0 B/op 0 allocs/op
BenchmarkIsValidName_Regex_Invalid-10 34824540 34.22 ns/op 0 B/op 0 allocs/op
BenchmarkIsValidName_Manual_Invalid-10 550804021 2.173 ns/op 0 B/op 0 allocs/op
BenchmarkIsValidName_Regex_Parallel-10 69289900 17.30 ns/op 0 B/op 0 allocs/op
BenchmarkIsValidName_Manual_Parallel-10 1000000000 0.9296 ns/op 0 B/op 0 allocs/op
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
6ec32660e9
commit
ab7018b590
|
|
@ -18,14 +18,9 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/cli/internal/lazyregexp"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
|
||||
|
||||
var restrictedNameRegEx = lazyregexp.New(restrictedNamePattern)
|
||||
|
||||
// Store provides a context store for easily remembering endpoints configuration
|
||||
type Store interface {
|
||||
Reader
|
||||
|
|
@ -225,12 +220,43 @@ func ValidateContextName(name string) error {
|
|||
if name == "default" {
|
||||
return errors.New(`"default" is a reserved context name`)
|
||||
}
|
||||
if !restrictedNameRegEx.MatchString(name) {
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
|
||||
if !isValidName(name) {
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, validNameFormat)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validNameFormat is used as part of errors for invalid context-names.
|
||||
// We should consider making this less technical ("must start with "a-z",
|
||||
// and only consist of alphanumeric characters and separators").
|
||||
const validNameFormat = `^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$`
|
||||
|
||||
// isValidName checks if the context-name is valid ("^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$").
|
||||
//
|
||||
// Names must start with an alphanumeric character (a-zA-Z0-9), followed by
|
||||
// alphanumeric or separators ("_", ".", "+", "-").
|
||||
func isValidName(s string) bool {
|
||||
if len(s) < 2 || !isAlphaNum(s[0]) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 1; i < len(s); i++ {
|
||||
c := s[i]
|
||||
if isAlphaNum(c) || c == '_' || c == '.' || c == '+' || c == '-' {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func isAlphaNum(c byte) bool {
|
||||
return (c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9')
|
||||
}
|
||||
|
||||
// Export exports an existing namespace into an opaque data stream
|
||||
// This stream is actually a tarball containing context metadata and TLS materials, but it does
|
||||
// not map 1:1 the layout of the context store (don't try to restore it manually without calling store.Import)
|
||||
|
|
|
|||
Loading…
Reference in New Issue