Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix: Regex for Cron Monitors
Resolves #4372
- #4372
  • Loading branch information
jamescrosswell committed Aug 4, 2025
commit b5a3a058d9113e473f8c6924d8460da903888d4a
6 changes: 4 additions & 2 deletions src/Sentry/SentryMonitorOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,17 @@ public partial class SentryMonitorOptions : ISentryJsonSerializable
// - Allows */n for step values where n must be any positive integer (except zero)
// - Allows single values within their valid ranges
// - Allows ranges (e.g., 8-10)
// - Allows step values with ranges (e.g., 8-18/4)
// - Allows lists of values and ranges (e.g., 6,8,9 or 8-10,12-14)
// - Allows weekday names (MON, TUE, WED, THU, FRI, SAT, SUN)
//
// Valid ranges for each field:
// - Minutes: 0-59
// - Hours: 0-23
// - Days: 1-31
// - Months: 1-12
// - Weekdays: 0-7 (0 and 7 both represent Sunday)
private const string ValidCrontabPattern = @"^(\*|(\*\/([1-9][0-9]*))|([0-5]?\d)(-[0-5]?\d)?)(,([0-5]?\d)(-[0-5]?\d)?)*(\s+)(\*|(\*\/([1-9][0-9]*))|([01]?\d|2[0-3])(-([01]?\d|2[0-3]))?)((,([01]?\d|2[0-3])(-([01]?\d|2[0-3]))?)*)?(\s+)(\*|(\*\/([1-9][0-9]*))|([1-9]|[12]\d|3[01])(-([1-9]|[12]\d|3[01]))?)((,([1-9]|[12]\d|3[01])(-([1-9]|[12]\d|3[01]))?)*)?(\s+)(\*|(\*\/([1-9][0-9]*))|([1-9]|1[0-2])(-([1-9]|1[0-2]))?)((,([1-9]|1[0-2])(-([1-9]|1[0-2]))?)*)?(\s+)(\*|(\*\/([1-9][0-9]*))|[0-7](-[0-7])?)((,[0-7](-[0-7])?)*)?$";
// - Weekdays: 0-7 (0 and 7 both represent Sunday) or MON-SUN
private const string ValidCrontabPattern = @"^(\*|(\*\/([1-9][0-9]*))|([0-5]?\d)(-[0-5]?\d)?(\/([1-9][0-9]*))?)(,(\*|(\*\/([1-9][0-9]*))|([0-5]?\d)(-[0-5]?\d)?(\/([1-9][0-9]*))?))*(\s+)(\*|(\*\/([1-9][0-9]*))|([01]?\d|2[0-3])(-([01]?\d|2[0-3]))?(\/([1-9][0-9]*))?)((,(\*|(\*\/([1-9][0-9]*))|([01]?\d|2[0-3])(-([01]?\d|2[0-3]))?(\/([1-9][0-9]*))?))*)?(\s+)(\*|(\*\/([1-9][0-9]*))|([1-9]|[12]\d|3[01])(-([1-9]|[12]\d|3[01]))?(\/([1-9][0-9]*))?)((,(\*|(\*\/([1-9][0-9]*))|([1-9]|[12]\d|3[01])(-([1-9]|[12]\d|3[01]))?(\/([1-9][0-9]*))?))*)?(\s+)(\*|(\*\/([1-9][0-9]*))|([1-9]|1[0-2])(-([1-9]|1[0-2]))?(\/([1-9][0-9]*))?)((,(\*|(\*\/([1-9][0-9]*))|([1-9]|1[0-2])(-([1-9]|1[0-2]))?(\/([1-9][0-9]*))?))*)?(\s+)(\*|(\*\/([1-9][0-9]*))|[0-7](-[0-7])?(\/([1-9][0-9]*))?|(MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?(\/([1-9][0-9]*))?)((,(\*|(\*\/([1-9][0-9]*))|[0-7](-[0-7])?(\/([1-9][0-9]*))?|(MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?(\/([1-9][0-9]*))?))*)?$";

private SentryMonitorScheduleType _type = SentryMonitorScheduleType.None;
private string? _crontab;
Expand Down
42 changes: 42 additions & 0 deletions test/Sentry.Tests/SentryMonitorOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,33 @@ day of month 1-31
[InlineData("0 0 1 1 0")] // Minimum values
[InlineData("*/1 * * * *")] // Step of 1
[InlineData("* * 31 */2 *")] // 31st of every other month
// Weekday names (GitHub issue #4372)
[InlineData("0 0 * * MON")]
[InlineData("0 9 * * MON-FRI")]
[InlineData("0 18 * * MON-FRI")]
[InlineData("0 0 * * MON-FRI")]
[InlineData("0 20 * * MON-FRI")]
// Step values with ranges
[InlineData("0-30/15 * * * *")] // Every 15 minutes from 0-30
[InlineData("0-59/10 * * * *")] // Every 10 minutes from 0-59
[InlineData("0-45/5 * * * *")] // Every 5 minutes from 0-45
[InlineData("* 8-18/2 * * *")] // Every 2 hours from 8-18
[InlineData("* 0-23/6 * * *")] // Every 6 hours from 0-23
[InlineData("* 9-17/1 * * *")] // Every hour from 9-17
[InlineData("* * 1-15/3 * *")] // Every 3 days from 1-15
[InlineData("* * 1-31/7 * *")] // Every 7 days from 1-31
[InlineData("* * 10-20/2 * *")] // Every 2 days from 10-20
[InlineData("* * * 1-6/2 *")] // Every 2 months from 1-6
[InlineData("* * * 1-12/3 *")] // Every 3 months from 1-12
[InlineData("* * * 3-9/1 *")] // Every month from 3-9
[InlineData("* * * * 1-5/2")] // Every 2 weekdays from 1-5 (Mon-Fri)
[InlineData("* * * * 0-6/3")] // Every 3 days of week from 0-6
[InlineData("* * * * MON-FRI/2")] // Every 2 weekdays from Mon-Fri
[InlineData("* * * * MON-SUN/3")] // Every 3 days from Mon-Sun
// Complex combinations with step values and ranges
[InlineData("0-30/15 8-18/2 * * *")] // Every 15 min from 0-30, every 2 hours from 8-18
[InlineData("0-45/5 9-17/1 1-15/3 * *")] // Complex combination
[InlineData("*/10 8-18/4 1-31/7 1-12/3 MON-FRI/2")] // All fields with step values and ranges
public void Interval_ValidCrontab_DoesNotThrow(string crontab)
{
// Arrange
Expand Down Expand Up @@ -101,6 +128,21 @@ public void Interval_SetMoreThanOnce_Throws()
[InlineData("*/* * * * *")] // Invalid step format
[InlineData(",1,2 * * * *")] // Leading comma
[InlineData("1,2, * * * *")] // Trailing comma
// Invalid step values with ranges
[InlineData("0-60/15 * * * *")] // Minute range exceeds 59
[InlineData("0-30/0 * * * *")] // Step value cannot be 0
[InlineData("0-30/-5 * * * *")] // Negative step value
[InlineData("* 8-25/2 * * *")] // Hour range exceeds 23
[InlineData("* 8-18/0 * * *")] // Step value cannot be 0
[InlineData("* * 0-31/3 * *")] // Day cannot be 0
[InlineData("* * 1-32/3 * *")] // Day range exceeds 31
[InlineData("* * * 0-12/2 *")] // Month cannot be 0
[InlineData("* * * 1-13/2 *")] // Month range exceeds 12
[InlineData("* * * * 0-8/2")] // Weekday range exceeds 7
[InlineData("* * * * MON-FRI/0")] // Step value cannot be 0
[InlineData("0-30//15 * * * *")] // Double slash
[InlineData("0-30/15/ * * * *")] // Trailing slash
[InlineData("0-30/15- * * * *")] // Incomplete range
public void CaptureCheckIn_InvalidCrontabSet_Throws(string crontab)
{
// Arrange
Expand Down
Loading