Expose ParseStrict to error on too many fields

Parse currently ignores any tokens after the 7th, which means invalid
cron expressions might be allowed as long as invalid tokens are found
after the 7th character.

In some use cases (e.g. validating cron expressions provided by a user),
this might not be desirable. To allow for this use case, this adds a
ParseStrict function that returns an error if too many fields are
provided (it retains backwards compatibility by not touching Parse).
This commit is contained in:
Thomas Orozco 2018-08-01 16:02:27 +02:00
parent 88b0669f7d
commit b648cc9a90
2 changed files with 35 additions and 2 deletions

View File

@ -62,11 +62,22 @@ func MustParse(cronLine string) *Expression {
/******************************************************************************/ /******************************************************************************/
// Parse returns a new Expression pointer. An error is returned if a malformed // Parse returns a new Expression pointer. An error is returned if a malformed
// cron expression is supplied. // cron expression is supplied. ParseStrict does the same thing, but unlike
// Parse, it will return an error if the provided cron line has too many
// tokens.
// See <https://github.com/gorhill/cronexpr#implementation> for documentation // See <https://github.com/gorhill/cronexpr#implementation> for documentation
// about what is a well-formed cron expression from this library's point of // about what is a well-formed cron expression from this library's point of
// view. // view.
func Parse(cronLine string) (*Expression, error) { func Parse(cronLine string) (*Expression, error) {
return parse(cronLine, false)
}
func ParseStrict(cronLine string) (*Expression, error) {
return parse(cronLine, true)
}
func parse(cronLine string, strict bool) (*Expression, error) {
// Maybe one of the built-in aliases is being used // Maybe one of the built-in aliases is being used
cron := cronNormalizer.Replace(cronLine) cron := cronNormalizer.Replace(cronLine)
@ -76,8 +87,14 @@ func Parse(cronLine string) (*Expression, error) {
if fieldCount < 5 { if fieldCount < 5 {
return nil, fmt.Errorf("missing field(s)") return nil, fmt.Errorf("missing field(s)")
} }
// ignore fields beyond 7th
if fieldCount > 7 { if fieldCount > 7 {
// In strict mode, error out
if strict {
return nil, fmt.Errorf("too many fields")
}
// In non-strict mode, ignore fields beyond 7th
fieldCount = 7 fieldCount = 7
} }

View File

@ -307,6 +307,22 @@ func TestInterval_Interval60Issue(t *testing.T) {
/******************************************************************************/ /******************************************************************************/
func TestTooManyFields(t *testing.T) {
cronLine := "* * * * * * * foobar"
_, err := ParseStrict(cronLine)
if err == nil {
t.Errorf("ParseStrict with too many fields should return err ")
}
_, err = Parse(cronLine)
if err != nil {
t.Errorf("Parse with too many fields should not return err ")
}
}
/******************************************************************************/
var benchmarkExpressions = []string{ var benchmarkExpressions = []string{
"* * * * *", "* * * * *",
"@hourly", "@hourly",