diff --git a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/PatternValidator.cs b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/PatternValidator.cs index 9c3d9da47..ec799c0bc 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/PatternValidator.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/PatternValidator.cs @@ -14,6 +14,7 @@ namespace Squidex.Domain.Apps.Core.ValidateContent.Validators { public class PatternValidator : IValidator { + private static readonly TimeSpan Timeout = TimeSpan.FromMilliseconds(20); private readonly Regex regex; private readonly string errorMessage; @@ -21,22 +22,32 @@ namespace Squidex.Domain.Apps.Core.ValidateContent.Validators { this.errorMessage = errorMessage; - regex = new Regex("^" + pattern + "$"); + regex = new Regex("^" + pattern + "$", RegexOptions.None, Timeout); } public Task ValidateAsync(object value, ValidationContext context, Action addError) { if (value is string stringValue) { - if (!string.IsNullOrEmpty(stringValue) && !regex.IsMatch(stringValue)) + if (!string.IsNullOrEmpty(stringValue)) { - if (string.IsNullOrWhiteSpace(errorMessage)) + try { - addError(" is not valid."); + if (!regex.IsMatch(stringValue)) + { + if (string.IsNullOrWhiteSpace(errorMessage)) + { + addError(" is not valid."); + } + else + { + addError(errorMessage); + } + } } - else + catch { - addError(errorMessage); + addError(" has a regex that is too slow."); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/PatternValidatorTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/PatternValidatorTests.cs index 79c054426..3b35d115d 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/PatternValidatorTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/Validators/PatternValidatorTests.cs @@ -68,5 +68,16 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent.Validators errors.ShouldBeEquivalentTo( new[] { "Custom Error Message." }); } + + [Fact] + public async Task Should_add_timeout_error_when_regex_is_too_slow() + { + var sut = new PatternValidator(@"^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$"); + + await sut.ValidateAsync("https://archiverbx.blob.core.windows.net/static/C:/Users/USR/Documents/Projects/PROJ/static/images/full/1234567890.jpg", errors); + + errors.ShouldBeEquivalentTo( + new[] { " has a regex that is too slow." }); + } } }