Skip to content

Commit ed04195

Browse files
committed
Add stricter func name validation
The valid function names contain a combination of lowercase letters, numbers and separators (., -, _). Name can only start and end with a letter or a number and there can only be one separator in the row (e.g. my---funcname is not valid, however my-func_name is valid). Fixes #503
1 parent dd5159e commit ed04195

2 files changed

Lines changed: 112 additions & 18 deletions

File tree

commands/init.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"os"
2929
"os/exec"
3030
"path/filepath"
31+
"regexp"
3132
"strings"
3233

3334
"github.com/fnproject/cli/common"
@@ -397,14 +398,14 @@ func (a *initFnCmd) bindFn(fn *modelsV2.Fn) {
397398
}
398399
}
399400

400-
// ValidateFuncName checks if the func name is valid, the name can't contain a colon and
401-
// must be all lowercase
401+
// ValidateFuncName checks if the func name is valid, the name can only contain alphanumerical
402+
// lowercase characters, separated by ., _ or -.
402403
func ValidateFuncName(name string) error {
403-
if strings.Contains(name, ":") {
404-
return errors.New("Function name cannot contain a colon")
405-
}
406-
if strings.ToLower(name) != name {
407-
return errors.New("Function name must be lowercase")
404+
// Match multiple groups of lowercase charaters and numbers, followed by 0 or 1 instances
405+
// of the separators; the string also needs to end with a character or a number (not separator)
406+
isValid := regexp.MustCompile(`^([a-z0-9]+[._-]?)*[a-z0-9]$`).MatchString
407+
if !isValid(name) {
408+
return errors.New("Function name cannot contain spaces, start with separators or contain uppercase letters")
408409
}
409410
return nil
410411
}

init_test.go

Lines changed: 104 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,110 @@ func TestInit(t *testing.T) {
5858
}
5959
}
6060

61-
func funcNameValidation(name string, t *testing.T) {
62-
err := commands.ValidateFuncName("fooFunc")
63-
if err == nil {
64-
t.Error("Expected validation error for function name")
61+
func TestFuncNameValidation(t *testing.T) {
62+
tc := []struct {
63+
name string
64+
value string
65+
errExpected bool
66+
}{
67+
{
68+
name: "strings only",
69+
value: "somename",
70+
errExpected: false,
71+
},
72+
{
73+
name: "numbers only",
74+
value: "12345",
75+
errExpected: false,
76+
},
77+
{
78+
name: "uppercase letters",
79+
value: "HelloFuncName",
80+
errExpected: true,
81+
},
82+
{
83+
name: "starts with separator",
84+
value: ".myfunc",
85+
errExpected: true,
86+
},
87+
{
88+
name: "starts with separator (*)",
89+
value: "*myfunc",
90+
errExpected: true,
91+
},
92+
{
93+
name: "starts with separator (-)",
94+
value: "-myfunc",
95+
errExpected: true,
96+
},
97+
{
98+
name: "ends with separator",
99+
value: "myfunc-",
100+
errExpected: true,
101+
},
102+
{
103+
name: "ends with separator (.)",
104+
value: "myfunc.",
105+
errExpected: true,
106+
},
107+
{
108+
name: "ends with separator (*)",
109+
value: "myfunc*",
110+
errExpected: true,
111+
},
112+
{
113+
name: "contains spaces",
114+
value: "my func blah",
115+
errExpected: true,
116+
},
117+
{
118+
name: "hypen in name",
119+
value: "my-func-blah",
120+
errExpected: false,
121+
},
122+
{
123+
name: "underscore in name",
124+
value: "my_funcblah",
125+
errExpected: false,
126+
},
127+
{
128+
name: "dot in name",
129+
value: "my.funcblah",
130+
errExpected: false,
131+
},
132+
{
133+
name: "multiple separators in row",
134+
value: "my___funcblah",
135+
errExpected: true,
136+
},
137+
{
138+
name: "multiple different separators in row",
139+
value: "my_.funcblah",
140+
errExpected: true,
141+
},
142+
{
143+
name: "multiple separators in the name",
144+
value: "my_func-blah.test",
145+
errExpected: false,
146+
},
65147
}
66-
}
67-
68-
func TestFuncNameWithUpperCase(t *testing.T) {
69-
funcNameValidation("fooMyFunc", t)
70-
}
71148

72-
func TestFuncNameWithColon(t *testing.T) {
73-
funcNameValidation("foo:myfunc", t)
149+
t.Log("Test func name validation")
150+
{
151+
for i, tst := range tc {
152+
t.Logf("\tTest %d: \t%s", i, tst.name)
153+
{
154+
err := commands.ValidateFuncName(tst.value)
155+
if err != nil {
156+
if !tst.errExpected {
157+
t.Fatalf("\tValidateFuncName failed : got unexpected error [%v]\n", err)
158+
}
159+
} else {
160+
if tst.errExpected {
161+
t.Fatalf("\tValidateFuncName failed : error expected for value '%s' but was nil\n", tst.value)
162+
}
163+
}
164+
}
165+
}
166+
}
74167
}

0 commit comments

Comments
 (0)