diff --git a/internal/executor/executor.go b/internal/executor/executor.go index ab37de2..02df5ea 100644 --- a/internal/executor/executor.go +++ b/internal/executor/executor.go @@ -10,6 +10,7 @@ import ( "context" "errors" "os/exec" + "net/url" "regexp" "strings" "time" @@ -279,11 +280,19 @@ func typecheckChoice(value string, arg *config.ActionArgument) error { // TypeSafetyCheck checks argument values match a specific type. The types are // defined in typecheckRegex, and, you guessed it, uses regex to check for allowed // characters. -func TypeSafetyCheck(name string, value string, typ string) error { - pattern, found := typecheckRegex[typ] +func TypeSafetyCheck(name string, value string, argumentType string) error { + if argumentType == "url" { + return typeSafetyCheckUrl(name, value) + } + + return typeSafetyCheckRegex(name, value, argumentType) +} + +func typeSafetyCheckRegex(name string, value string, argumentType string) error { + pattern, found := typecheckRegex[argumentType] if !found { - return errors.New("argument type not implemented " + typ) + return errors.New("argument type not implemented " + argumentType) } matches, _ := regexp.MatchString(pattern, value) @@ -291,12 +300,18 @@ func TypeSafetyCheck(name string, value string, typ string) error { if !matches { log.WithFields(log.Fields{ "name": name, - "type": typ, "value": value, + "type": argumentType, }).Warn("Arg type check safety failure") - return errors.New("invalid argument, doesn't match " + typ) + return errors.New("invalid argument, doesn't match " + argumentType) } return nil } + +func typeSafetyCheckUrl(name string, value string) error { + _, err := url.ParseRequestURI(value) + + return err +} diff --git a/internal/executor/executor_test.go b/internal/executor/executor_test.go index 4ab8766..b9e76d6 100644 --- a/internal/executor/executor_test.go +++ b/internal/executor/executor_test.go @@ -161,3 +161,12 @@ func TestArgumentNotProvided(t *testing.T) { assert.Equal(t, "", out) assert.Equal(t, err.Error(), "Required arg not provided: personName") } + +func TestTypeSafetyCheckUrl(t *testing.T) { + assert.Nil(t, TypeSafetyCheck("test1", "http://google.com", "url"), "Test URL: google.com") + assert.Nil(t, TypeSafetyCheck("test2", "http://technowax.net:80?foo=bar", "url"), "Test URL: technowax.net with query arguments") + assert.Nil(t, TypeSafetyCheck("test3", "http://localhost:80?foo=bar", "url"), "Test URL: localhost with query arguments") + assert.NotNil(t, TypeSafetyCheck("test4", "http://lo host:80", "url"), "Test a badly formed URL") + assert.NotNil(t, TypeSafetyCheck("test5", "12345", "url"), "Test a badly formed URL") + assert.NotNil(t, TypeSafetyCheck("test6", "_!23;", "url"), "Test a badly formed URL") +}