Skip to content

Commit 2caf888

Browse files
author
rstam
committed
Escape special characters in regular expressions generated for LINQ queries involving strings.
1 parent 2b9e193 commit 2caf888

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

Driver/Linq/Translators/SelectQuery.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ private IMongoQuery BuildStringQuery(MethodCallExpression methodCallExpression)
824824
return null;
825825
}
826826

827-
var pattern = (string)constantExpression.Value; // TODO: escape value
827+
var pattern = Regex.Escape((string)constantExpression.Value);
828828
switch (methodCallExpression.Method.Name)
829829
{
830830
case "Contains": pattern = ".*" + pattern + ".*"; break;
@@ -1103,8 +1103,7 @@ private string GetTrimCharsPattern(Expression trimCharsExpression)
11031103
}
11041104
else
11051105
{
1106-
// TODO: handle special characters better
1107-
sb.Append(c.ToString());
1106+
sb.Append(Regex.Escape(c.ToString()));
11081107
}
11091108
}
11101109
if (sawDash)

DriverUnitTests/Linq/SelectQueryTests.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4259,6 +4259,29 @@ public void TestWhereSContainsAbcNot()
42594259
Assert.AreEqual(4, Consume(query));
42604260
}
42614261

4262+
[Test]
4263+
public void TestWhereSContainsDot()
4264+
{
4265+
var query = from c in _collection.AsQueryable<C>()
4266+
where c.S.Contains(".")
4267+
select c;
4268+
4269+
var translatedQuery = MongoQueryTranslator.Translate(query);
4270+
Assert.IsInstanceOf<SelectQuery>(translatedQuery);
4271+
Assert.AreSame(_collection, translatedQuery.Collection);
4272+
Assert.AreSame(typeof(C), translatedQuery.DocumentType);
4273+
4274+
var selectQuery = (SelectQuery)translatedQuery;
4275+
Assert.AreEqual("(C c) => c.S.Contains(\".\")", ExpressionFormatter.ToString(selectQuery.Where));
4276+
Assert.IsNull(selectQuery.OrderBy);
4277+
Assert.IsNull(selectQuery.Projection);
4278+
Assert.IsNull(selectQuery.Skip);
4279+
Assert.IsNull(selectQuery.Take);
4280+
4281+
Assert.AreEqual("{ \"s\" : /\\./s }", selectQuery.BuildQuery().ToJson());
4282+
Assert.AreEqual(0, Consume(query));
4283+
}
4284+
42624285
[Test]
42634286
public void TestWhereSEndsWithAbc()
42644287
{
@@ -4794,7 +4817,7 @@ public void TestWhereSTrimStartsWithXyzNot()
47944817
public void TestWhereSTrimStartTrimEndToLowerContainsXyz()
47954818
{
47964819
var query = from c in _collection.AsQueryable<C>()
4797-
where c.S.TrimStart(' ', '-', '\t').TrimEnd().ToLower().Contains("xyz")
4820+
where c.S.TrimStart(' ', '.', '-', '\t').TrimEnd().ToLower().Contains("xyz")
47984821
select c;
47994822

48004823
var translatedQuery = MongoQueryTranslator.Translate(query);
@@ -4803,13 +4826,13 @@ where c.S.TrimStart(' ', '-', '\t').TrimEnd().ToLower().Contains("xyz")
48034826
Assert.AreSame(typeof(C), translatedQuery.DocumentType);
48044827

48054828
var selectQuery = (SelectQuery)translatedQuery;
4806-
Assert.AreEqual("(C c) => c.S.TrimStart(Char[]:{ ' ', '-', '\t' }).TrimEnd(Char[]:{ }).ToLower().Contains(\"xyz\")", ExpressionFormatter.ToString(selectQuery.Where));
4829+
Assert.AreEqual("(C c) => c.S.TrimStart(Char[]:{ ' ', '.', '-', '\t' }).TrimEnd(Char[]:{ }).ToLower().Contains(\"xyz\")", ExpressionFormatter.ToString(selectQuery.Where));
48074830
Assert.IsNull(selectQuery.OrderBy);
48084831
Assert.IsNull(selectQuery.Projection);
48094832
Assert.IsNull(selectQuery.Skip);
48104833
Assert.IsNull(selectQuery.Take);
48114834

4812-
Assert.AreEqual("{ \"s\" : /^[ \t-]*.*xyz.*\\s*$/is }", selectQuery.BuildQuery().ToJson());
4835+
Assert.AreEqual("{ \"s\" : /^[\\ \\.\\t-]*.*xyz.*\\s*$/is }", selectQuery.BuildQuery().ToJson());
48134836
Assert.AreEqual(1, Consume(query));
48144837
}
48154838

0 commit comments

Comments
 (0)