@@ -750,6 +750,12 @@ private IMongoQuery BuildQuery(Expression expression)
750
750
751
751
private IMongoQuery BuildStringIndexOfQuery ( Expression variableExpression , ExpressionType operatorType , ConstantExpression constantExpression )
752
752
{
753
+ // TODO: support other comparison operators
754
+ if ( operatorType != ExpressionType . Equal )
755
+ {
756
+ return null ;
757
+ }
758
+
753
759
if ( constantExpression . Type != typeof ( int ) )
754
760
{
755
761
return null ;
@@ -803,51 +809,68 @@ private IMongoQuery BuildStringIndexOfQuery(Expression variableExpression, Expre
803
809
string pattern = null ;
804
810
if ( value . GetType ( ) == typeof ( char ) )
805
811
{
806
- var c = Regex . Escape ( ( ( char ) value ) . ToString ( ) ) ;
812
+ var escapedChar = Regex . Escape ( ( ( char ) value ) . ToString ( ) ) ;
807
813
if ( startIndex == - 1 )
808
814
{
809
815
// the regex for: IndexOf(c) == index
810
816
// is: /^[^c]{index}c/
811
- pattern = string . Format ( "^[^{0}]{{{1}}}{0}" , c , index ) ;
817
+ pattern = string . Format ( "^[^{0}]{{{1}}}{0}" , escapedChar , index ) ;
812
818
}
813
819
else
814
820
{
815
821
if ( count == - 1 )
816
822
{
817
823
// the regex for: IndexOf(c, startIndex) == index
818
824
// is: /^.{startIndex}[^c]{index - startIndex}c/
819
- pattern = string . Format ( "^.{{{1}}}[^{0}]{{{2}}}{0}" , c , startIndex , index - startIndex ) ;
825
+ pattern = string . Format ( "^.{{{1}}}[^{0}]{{{2}}}{0}" , escapedChar , startIndex , index - startIndex ) ;
820
826
}
821
827
else
822
828
{
823
- // the regex for: IndexOf(c, startIndex, count) == index
824
- // is: /^.{startIndex}(?=.{count})[^c]{index - startIndex}c/
825
- pattern = string . Format ( "^.{{{1}}}(?=.{{{2}}})[^{0}]{{{3}}}{0}" , c , startIndex , count , index - startIndex ) ;
829
+ if ( index >= startIndex + count )
830
+ {
831
+ // index is outside of the substring so no match is possible
832
+ return Query . Exists ( "_id" , false ) ; // matches no documents
833
+ }
834
+ else
835
+ {
836
+ // the regex for: IndexOf(c, startIndex, count) == index
837
+ // is: /^.{startIndex}(?=.{count})[^c]{index - startIndex}c/
838
+ pattern = string . Format ( "^.{{{1}}}(?=.{{{2}}})[^{0}]{{{3}}}{0}" , escapedChar , startIndex , count , index - startIndex ) ;
839
+ }
826
840
}
827
841
}
828
842
}
829
843
else if ( value . GetType ( ) == typeof ( string ) )
830
844
{
831
- var s = Regex . Escape ( ( string ) value ) ;
845
+ var escapedString = Regex . Escape ( ( string ) value ) ;
832
846
if ( startIndex == - 1 )
833
847
{
834
848
// the regex for: IndexOf(s) == index
835
849
// is: /^(?!.{0,index - 1}s).{index}s/
836
- pattern = string . Format ( "^(?!.{{0,{2}}}{0}).{{{1}}}{0}" , s , index , index - 1 ) ;
850
+ pattern = string . Format ( "^(?!.{{0,{2}}}{0}).{{{1}}}{0}" , escapedString , index , index - 1 ) ;
837
851
}
838
852
else
839
853
{
840
854
if ( count == - 1 )
841
855
{
842
856
// the regex for: IndexOf(s, startIndex) == index
843
857
// is: /^.{startIndex}(?!.{0, index - startIndex - 1}s).{index - startIndex}s/
844
- pattern = string . Format ( "^.{{{1}}}(?!.{{0,{2}}}{0}).{{{3}}}{0}" , s , startIndex , index - startIndex - 1 , index - startIndex ) ;
858
+ pattern = string . Format ( "^.{{{1}}}(?!.{{0,{2}}}{0}).{{{3}}}{0}" , escapedString , startIndex , index - startIndex - 1 , index - startIndex ) ;
845
859
}
846
860
else
847
861
{
848
- // the regex for: IndexOf(s, startIndex, count) == index
849
- // is: /^.{startIndex}(?=.{count})(?!.{0,index - startIndex - 1}s).{index - startIndex)s/
850
- pattern = string . Format ( "^.{{{1}}}(?=.{{{2}}})(?!.{{0,{3}}}{0}).{{{4}}}{0}" , s , startIndex , count , index - startIndex - 1 , index - startIndex ) ;
862
+ var unescapedLength = ( ( string ) value ) . Length ;
863
+ if ( unescapedLength > startIndex + count - index )
864
+ {
865
+ // substring isn't long enough to match
866
+ return Query . Exists ( "_id" , false ) ; // matches no documents
867
+ }
868
+ else
869
+ {
870
+ // the regex for: IndexOf(s, startIndex, count) == index
871
+ // is: /^.{startIndex}(?=.{count})(?!.{0,index - startIndex - 1}s).{index - startIndex)s/
872
+ pattern = string . Format ( "^.{{{1}}}(?=.{{{2}}})(?!.{{0,{3}}}{0}).{{{4}}}{0}" , escapedString , startIndex , count , index - startIndex - 1 , index - startIndex ) ;
873
+ }
851
874
}
852
875
}
853
876
}
0 commit comments