diff --git a/plugins/common/common.go b/plugins/common/common.go index a3ec11acd..227c18b50 100644 --- a/plugins/common/common.go +++ b/plugins/common/common.go @@ -923,26 +923,26 @@ func IsValidAppName(appName string) error { return errors.New("Please specify an app to run the command on") } - r, _ := regexp.Compile("^[a-z0-9][^/:_A-Z]*$") + r, _ := regexp.Compile("^[a-z0-9][a-z0-9.-]*$") if r.MatchString(appName) { return nil } - return errors.New("App name must begin with lowercase alphanumeric character, and cannot include uppercase characters, colons, or underscores") + return errors.New("App name must begin with lowercase alphanumeric character, and may only contain lowercase alphanumerics, dots, and hyphens") } -// isValidAppNameOld verifies that the app name matches the old naming restrictions -func isValidAppNameOld(appName string) error { +// IsValidAppNameOld verifies that the app name matches the old naming restrictions +func IsValidAppNameOld(appName string) error { if appName == "" { return errors.New("Please specify an app to run the command on") } - r, _ := regexp.Compile("^[a-z0-9][^/:A-Z]*$") + r, _ := regexp.Compile("^[a-z0-9][a-z0-9._-]*$") if r.MatchString(appName) { return nil } - return errors.New("App name must begin with lowercase alphanumeric character, and cannot include uppercase characters, or colons") + return errors.New("App name must begin with lowercase alphanumeric character, and may only contain lowercase alphanumerics, dots, hyphens, and underscores") } // AppDoesNotExist wraps error to include the app name @@ -981,7 +981,7 @@ func VarArgs(arguments []string, skip int) []string { // naming conventions exists func VerifyAppName(appName string) error { newErr := IsValidAppName(appName) - oldErr := isValidAppNameOld(appName) + oldErr := IsValidAppNameOld(appName) if newErr != nil && oldErr != nil { return newErr } diff --git a/plugins/common/common_test.go b/plugins/common/common_test.go index f6fa98123..0123a6c56 100644 --- a/plugins/common/common_test.go +++ b/plugins/common/common_test.go @@ -77,6 +77,90 @@ func TestCommonVerifyAppNameInvalid(t *testing.T) { Expect(VerifyAppName("1994testApp")).To(HaveOccurred()) } +func TestCommonIsValidAppName(t *testing.T) { + RegisterTestingT(t) + validNames := []string{ + "myapp", + "my-app", + "my.app", + "app123", + "123app", + "my-app.prod", + "a", + "0", + } + for _, name := range validNames { + Expect(IsValidAppName(name)).To(Succeed(), "expected %q to be a valid app name", name) + } +} + +func TestCommonIsValidAppNameOld(t *testing.T) { + RegisterTestingT(t) + validNames := []string{ + "myapp", + "my-app", + "my.app", + "my_app", + "legacy_app_name", + "app_v2", + } + for _, name := range validNames { + Expect(IsValidAppNameOld(name)).To(Succeed(), "expected %q to be a valid app name", name) + } + + invalidNames := []string{ + "app;id", + "app$cmd", + "app|cat", + "app/cmd", + "app:cmd", + "App", + "-app", + "_app", + "", + } + for _, name := range invalidNames { + Expect(IsValidAppNameOld(name)).To(HaveOccurred(), "expected %q to be rejected", name) + } +} + +func TestCommonIsValidAppNameRejectsShellMetacharacters(t *testing.T) { + RegisterTestingT(t) + invalidNames := []string{ + "app;id", + "app$cmd", + "app`whoami`", + "app|cat", + "app&background", + "app>file", + "app