diff --git a/Sieve/Models/FilterTerm.cs b/Sieve/Models/FilterTerm.cs index 77bfeec..f2fd6ee 100644 --- a/Sieve/Models/FilterTerm.cs +++ b/Sieve/Models/FilterTerm.cs @@ -9,6 +9,7 @@ public class FilterTerm : IFilterTerm, IEquatable public FilterTerm() { } private const string EscapedPipePattern = @"(? t.Trim()).ToArray(); Names = Regex.Split(filterSplits[0], EscapedPipePattern).Select(t => t.Trim()).ToArray(); - Values = filterSplits.Length > 1 ? Regex.Split(filterSplits[1], EscapedPipePattern).Select(t => t.Trim()).ToArray() : null; + Values = filterSplits.Length > 1 + ? Regex.Split(filterSplits[1], EscapedPipePattern) + .Select(t => t.Replace(PipeToEscape, "|").Trim()) + .ToArray() + : null; Operator = Array.Find(Operators, o => value.Contains(o)) ?? "=="; OperatorParsed = GetOperatorParsed(Operator); OperatorIsCaseInsensitive = Operator.EndsWith("*"); @@ -90,6 +95,5 @@ public bool Equals(FilterTerm other) && Values.SequenceEqual(other.Values) && Operator == other.Operator; } - } } diff --git a/Sieve/Models/SieveModel.cs b/Sieve/Models/SieveModel.cs index a3f9818..8d43153 100644 --- a/Sieve/Models/SieveModel.cs +++ b/Sieve/Models/SieveModel.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; diff --git a/SieveUnitTests/General.cs b/SieveUnitTests/General.cs index f12e5a3..a59c15f 100644 --- a/SieveUnitTests/General.cs +++ b/SieveUnitTests/General.cs @@ -613,5 +613,61 @@ public void BaseDefinedPropertyMappingSortingWorks_WithCustomName() Assert.Equal(1,posts[2].Id); Assert.Equal(0,posts[3].Id); } + + [Fact] + public void CanFilter_WithEscapeCharacter() + { + var comments = new List + { + new Comment + { + Id = 0, + DateCreated = DateTimeOffset.UtcNow, + Text = "Here is, a comment" + }, + new Comment + { + Id = 1, + DateCreated = DateTimeOffset.UtcNow.AddDays(-1), + Text = "Here is, another comment" + }, + }.AsQueryable(); + + var model = new SieveModel + { + Filters = "Text==Here is\\, another comment" + }; + + var result = _processor.Apply(model, comments); + Assert.Equal(1, result.Count()); + } + + [Fact] + public void OrEscapedPipeValueFilteringWorks() + { + var comments = new List + { + new Comment + { + Id = 0, + DateCreated = DateTimeOffset.UtcNow, + Text = "Here is | a comment" + }, + new Comment + { + Id = 1, + DateCreated = DateTimeOffset.UtcNow.AddDays(-1), + Text = "Here is | another comment" + }, + }.AsQueryable(); + + var model = new SieveModel() + { + Filters = "Text==Here is \\| a comment|Here is \\| another comment", + }; + + var result = _processor.Apply(model, comments); + Assert.Equal(2, result.Count()); + } } }