Skip to content

Commit

Permalink
Add stricter func name validation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
peterj committed Mar 1, 2019
1 parent dd5159e commit ed04195
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 18 deletions.
15 changes: 8 additions & 7 deletions commands/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"

"github.com/fnproject/cli/common"
Expand Down Expand Up @@ -397,14 +398,14 @@ func (a *initFnCmd) bindFn(fn *modelsV2.Fn) {
}
}

// ValidateFuncName checks if the func name is valid, the name can't contain a colon and
// must be all lowercase
// ValidateFuncName checks if the func name is valid, the name can only contain alphanumerical
// lowercase characters, separated by ., _ or -.
func ValidateFuncName(name string) error {
if strings.Contains(name, ":") {
return errors.New("Function name cannot contain a colon")
}
if strings.ToLower(name) != name {
return errors.New("Function name must be lowercase")
// Match multiple groups of lowercase charaters and numbers, followed by 0 or 1 instances
// of the separators; the string also needs to end with a character or a number (not separator)
isValid := regexp.MustCompile(`^([a-z0-9]+[._-]?)*[a-z0-9]$`).MatchString
if !isValid(name) {
return errors.New("Function name cannot contain spaces, start with separators or contain uppercase letters")
}
return nil
}
Expand Down
115 changes: 104 additions & 11 deletions init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,110 @@ func TestInit(t *testing.T) {
}
}

func funcNameValidation(name string, t *testing.T) {
err := commands.ValidateFuncName("fooFunc")
if err == nil {
t.Error("Expected validation error for function name")
func TestFuncNameValidation(t *testing.T) {
tc := []struct {
name string
value string
errExpected bool
}{
{
name: "strings only",
value: "somename",
errExpected: false,
},
{
name: "numbers only",
value: "12345",
errExpected: false,
},
{
name: "uppercase letters",
value: "HelloFuncName",
errExpected: true,
},
{
name: "starts with separator",
value: ".myfunc",
errExpected: true,
},
{
name: "starts with separator (*)",
value: "*myfunc",
errExpected: true,
},
{
name: "starts with separator (-)",
value: "-myfunc",
errExpected: true,
},
{
name: "ends with separator",
value: "myfunc-",
errExpected: true,
},
{
name: "ends with separator (.)",
value: "myfunc.",
errExpected: true,
},
{
name: "ends with separator (*)",
value: "myfunc*",
errExpected: true,
},
{
name: "contains spaces",
value: "my func blah",
errExpected: true,
},
{
name: "hypen in name",
value: "my-func-blah",
errExpected: false,
},
{
name: "underscore in name",
value: "my_funcblah",
errExpected: false,
},
{
name: "dot in name",
value: "my.funcblah",
errExpected: false,
},
{
name: "multiple separators in row",
value: "my___funcblah",
errExpected: true,
},
{
name: "multiple different separators in row",
value: "my_.funcblah",
errExpected: true,
},
{
name: "multiple separators in the name",
value: "my_func-blah.test",
errExpected: false,
},
}
}

func TestFuncNameWithUpperCase(t *testing.T) {
funcNameValidation("fooMyFunc", t)
}

func TestFuncNameWithColon(t *testing.T) {
funcNameValidation("foo:myfunc", t)
t.Log("Test func name validation")
{
for i, tst := range tc {
t.Logf("\tTest %d: \t%s", i, tst.name)
{
err := commands.ValidateFuncName(tst.value)
if err != nil {
if !tst.errExpected {
t.Fatalf("\tValidateFuncName failed : got unexpected error [%v]\n", err)
}
} else {
if tst.errExpected {
t.Fatalf("\tValidateFuncName failed : error expected for value '%s' but was nil\n", tst.value)
}
}
}
}
}
}

0 comments on commit ed04195

Please sign in to comment.