@@ -18,14 +18,9 @@ import (
1818 "path/filepath"
1919 "strings"
2020
21- "github.com/docker/cli/internal/lazyregexp"
2221 "github.com/opencontainers/go-digest"
2322)
2423
25- const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
26-
27- var restrictedNameRegEx = lazyregexp .New (restrictedNamePattern )
28-
2924// Store provides a context store for easily remembering endpoints configuration
3025type Store interface {
3126 Reader
@@ -225,12 +220,43 @@ func ValidateContextName(name string) error {
225220 if name == "default" {
226221 return errors .New (`"default" is a reserved context name` )
227222 }
228- if ! restrictedNameRegEx . MatchString (name ) {
229- return fmt .Errorf ("context name %q is invalid, names are validated against regexp %q" , name , restrictedNamePattern )
223+ if ! isValidName (name ) {
224+ return fmt .Errorf ("context name %q is invalid, names are validated against regexp %q" , name , validNameFormat )
230225 }
231226 return nil
232227}
233228
229+ // validNameFormat is used as part of errors for invalid context-names.
230+ // We should consider making this less technical ("must start with "a-z",
231+ // and only consist of alphanumeric characters and separators").
232+ const validNameFormat = `^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$`
233+
234+ // isValidName checks if the context-name is valid ("^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$").
235+ //
236+ // Names must start with an alphanumeric character (a-zA-Z0-9), followed by
237+ // alphanumeric or separators ("_", ".", "+", "-").
238+ func isValidName (s string ) bool {
239+ if len (s ) < 2 || ! isAlphaNum (s [0 ]) {
240+ return false
241+ }
242+
243+ for i := 1 ; i < len (s ); i ++ {
244+ c := s [i ]
245+ if isAlphaNum (c ) || c == '_' || c == '.' || c == '+' || c == '-' {
246+ continue
247+ }
248+ return false
249+ }
250+
251+ return true
252+ }
253+
254+ func isAlphaNum (c byte ) bool {
255+ return (c >= 'a' && c <= 'z' ) ||
256+ (c >= 'A' && c <= 'Z' ) ||
257+ (c >= '0' && c <= '9' )
258+ }
259+
234260// Export exports an existing namespace into an opaque data stream
235261// This stream is actually a tarball containing context metadata and TLS materials, but it does
236262// not map 1:1 the layout of the context store (don't try to restore it manually without calling store.Import)
0 commit comments