@@ -16,11 +16,28 @@ var cronDetectionLog = logger.New("parser:schedule_cron_detection")
1616// cronFieldPattern matches valid cron field syntax (pre-compiled for performance)
1717var cronFieldPattern = regexp .MustCompile (`^[\d\*\-/,]+$` )
1818
19+ func cronFields (cron string ) ([]string , bool ) {
20+ fields := strings .Fields (cron )
21+ return fields , len (fields ) == 5
22+ }
23+
24+ func isNumericCronField (field string ) bool {
25+ if field == "" {
26+ return false
27+ }
28+ for _ , ch := range field {
29+ if ch < '0' || ch > '9' {
30+ return false
31+ }
32+ }
33+ return true
34+ }
35+
1936// IsDailyCron checks if a cron expression represents a daily schedule at a fixed time
2037// (e.g., "0 0 * * *", "30 14 * * *", etc.)
2138func IsDailyCron (cron string ) bool {
22- fields := strings . Fields (cron )
23- if len ( fields ) != 5 {
39+ fields , ok := cronFields (cron )
40+ if ! ok {
2441 return false
2542 }
2643 // Daily pattern: minute hour * * *
@@ -32,16 +49,8 @@ func IsDailyCron(cron string) bool {
3249 minute := fields [0 ]
3350 hour := fields [1 ]
3451
35- // Minute and hour should be digits only (no *, /, -, ,)
36- for _ , ch := range minute {
37- if ch < '0' || ch > '9' {
38- return false
39- }
40- }
41- for _ , ch := range hour {
42- if ch < '0' || ch > '9' {
43- return false
44- }
52+ if ! isNumericCronField (minute ) || ! isNumericCronField (hour ) {
53+ return false
4554 }
4655
4756 result := fields [2 ] == "*" && fields [3 ] == "*" && fields [4 ] == "*"
@@ -54,8 +63,8 @@ func IsDailyCron(cron string) bool {
5463// IsHourlyCron checks if a cron expression represents an hourly interval with a fixed minute
5564// (e.g., "0 */1 * * *", "30 */2 * * *", etc.)
5665func IsHourlyCron (cron string ) bool {
57- fields := strings . Fields (cron )
58- if len ( fields ) != 5 {
66+ fields , ok := cronFields (cron )
67+ if ! ok {
5968 return false
6069 }
6170 // Hourly pattern: minute */N * * * or minute *N * * *
@@ -65,11 +74,8 @@ func IsHourlyCron(cron string) bool {
6574 minute := fields [0 ]
6675 hour := fields [1 ]
6776
68- // Minute should be digits only (no *, /, -, ,)
69- for _ , ch := range minute {
70- if ch < '0' || ch > '9' {
71- return false
72- }
77+ if ! isNumericCronField (minute ) {
78+ return false
7379 }
7480
7581 // Hour should be an interval pattern like */N
@@ -88,8 +94,8 @@ func IsHourlyCron(cron string) bool {
8894// IsWeeklyCron checks if a cron expression represents a weekly schedule at a fixed time
8995// (e.g., "0 0 * * 1", "30 14 * * 5", etc.)
9096func IsWeeklyCron (cron string ) bool {
91- fields := strings . Fields (cron )
92- if len ( fields ) != 5 {
97+ fields , ok := cronFields (cron )
98+ if ! ok {
9399 return false
94100 }
95101 // Weekly pattern: minute hour * * DOW
@@ -101,16 +107,8 @@ func IsWeeklyCron(cron string) bool {
101107 minute := fields [0 ]
102108 hour := fields [1 ]
103109
104- // Minute and hour should be digits only (no *, /, -, ,)
105- for _ , ch := range minute {
106- if ch < '0' || ch > '9' {
107- return false
108- }
109- }
110- for _ , ch := range hour {
111- if ch < '0' || ch > '9' {
112- return false
113- }
110+ if ! isNumericCronField (minute ) || ! isNumericCronField (hour ) {
111+ return false
114112 }
115113
116114 // Check day-of-month and month are wildcards
0 commit comments