diff --git a/cronexpr.go b/cronexpr.go index 58b518f..3bb6571 100644 --- a/cronexpr.go +++ b/cronexpr.go @@ -62,11 +62,22 @@ func MustParse(cronLine string) *Expression { /******************************************************************************/ // 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 for documentation // about what is a well-formed cron expression from this library's point of // view. + 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 cron := cronNormalizer.Replace(cronLine) @@ -76,8 +87,14 @@ func Parse(cronLine string) (*Expression, error) { if fieldCount < 5 { return nil, fmt.Errorf("missing field(s)") } - // ignore fields beyond 7th + 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 } diff --git a/cronexpr/go.mod b/cronexpr/go.mod new file mode 100644 index 0000000..128fd22 --- /dev/null +++ b/cronexpr/go.mod @@ -0,0 +1,7 @@ +module github.com/krallin/cronexpr/cronexpr + +go 1.14 + +replace github.com/krallin/cronexpr => ../ + +require github.com/krallin/cronexpr v0.0.0-00010101000000-000000000000 diff --git a/cronexpr/go.sum b/cronexpr/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/cronexpr/main.go b/cronexpr/main.go index 1d9abe5..e33213e 100644 --- a/cronexpr/main.go +++ b/cronexpr/main.go @@ -18,7 +18,7 @@ import ( "os" "time" - "github.com/gorhill/cronexpr" + "github.com/krallin/cronexpr" ) /******************************************************************************/ diff --git a/cronexpr_parse.go b/cronexpr_parse.go index a9fe746..27683c6 100644 --- a/cronexpr_parse.go +++ b/cronexpr_parse.go @@ -438,6 +438,9 @@ func genericFieldParse(s string, desc fieldDescriptor) ([]*cronDirective, error) directive.first = desc.atoi(snormal[pairs[2]:pairs[3]]) directive.last = desc.atoi(snormal[pairs[4]:pairs[5]]) directive.step = 1 + if directive.last < directive.first { + return nil, fmt.Errorf("invalid interval %s (normalized to %d-%d)", snormal, directive.first, directive.last) + } directives = append(directives, &directive) continue } diff --git a/cronexpr_test.go b/cronexpr_test.go index 6ccf7ab..8bf8d4d 100644 --- a/cronexpr_test.go +++ b/cronexpr_test.go @@ -305,6 +305,35 @@ func TestInterval_Interval60Issue(t *testing.T) { } } +// Issue: https://github.com/aptible/supercronic/issues/63 +func TestRange_OutOfOrder(t *testing.T) { + _, err := Parse("45 4 * * 6-7") + if err == nil { + t.Errorf("parsing with range 6-7 should return err") + } + + _, err = Parse("45 4 * * 6-5") + if err == nil { + t.Errorf("parsing with range 6-5 should return err") + } +} + +/******************************************************************************/ + +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{ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1af9dc3 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/krallin/cronexpr + +go 1.14