57 lines
1.4 KiB
Go
57 lines
1.4 KiB
Go
package routing
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"regexp"
|
||
|
|
"strings"
|
||
|
|
)
|
||
|
|
|
||
|
|
// validateCronExpression validates a cron expression (simplified)
|
||
|
|
// Supports standard 5-field cron: minute hour day month weekday
|
||
|
|
// Does NOT validate all possible edge cases - just basic format
|
||
|
|
func validateCronExpression(expr string) error {
|
||
|
|
fields := strings.Fields(expr)
|
||
|
|
if len(fields) != 5 {
|
||
|
|
return fmt.Errorf("cron expression must have 5 fields (minute hour day month weekday), got %d", len(fields))
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate field ranges
|
||
|
|
ranges := []struct {
|
||
|
|
name string
|
||
|
|
min int
|
||
|
|
max int
|
||
|
|
}{
|
||
|
|
{"minute", 0, 59},
|
||
|
|
{"hour", 0, 23},
|
||
|
|
{"day", 1, 31},
|
||
|
|
{"month", 1, 12},
|
||
|
|
{"weekday", 0, 6},
|
||
|
|
}
|
||
|
|
|
||
|
|
// Basic pattern: * or */n or n or n-m or n,m or n-m/p
|
||
|
|
// This is simplified and doesn't validate all edge cases
|
||
|
|
fieldRegex := regexp.MustCompile(`^(\*|(\d+)(,(\d+))*(\/\d+)?|(\d+)-(\d+)(\/\d+)?|\*\/\d+)$`)
|
||
|
|
|
||
|
|
for i, field := range fields {
|
||
|
|
if field == "*" {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check basic format
|
||
|
|
if !fieldRegex.MatchString(field) {
|
||
|
|
return fmt.Errorf("invalid %s field: %s", ranges[i].name, field)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate simple number values
|
||
|
|
if !strings.ContainsAny(field, "*,-/") {
|
||
|
|
var val int
|
||
|
|
_, _ = fmt.Sscanf(field, "%d", &val)
|
||
|
|
if val < ranges[i].min || val > ranges[i].max {
|
||
|
|
return fmt.Errorf("invalid %s value %d (range %d-%d)", ranges[i].name, val, ranges[i].min, ranges[i].max)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|