Repository: activemq-artemis
Updated Branches:
  refs/heads/master 1c782e0bc -> 66c1c210e


ARTEMIS-356 - better support for special characters in like selector escape

https://issues.apache.org/jira/browse/ARTEMIS-356
https://issues.apache.org/jira/browse/AMQ-6137


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/a337df70
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/a337df70
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/a337df70

Branch: refs/heads/master
Commit: a337df705e3a52146a8cf6c57941cbd675f12b00
Parents: 1c782e0
Author: gtully <[email protected]>
Authored: Fri Jan 22 16:19:49 2016 +0000
Committer: gtully <[email protected]>
Committed: Fri Jan 22 16:30:16 2016 +0000

----------------------------------------------------------------------
 .../selector/filter/ComparisonExpression.java   | 44 ++++++++++++--------
 .../activemq/artemis/selector/SelectorTest.java | 17 ++++++++
 2 files changed, 44 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a337df70/artemis-selector/src/main/java/org/apache/activemq/artemis/selector/filter/ComparisonExpression.java
----------------------------------------------------------------------
diff --git 
a/artemis-selector/src/main/java/org/apache/activemq/artemis/selector/filter/ComparisonExpression.java
 
b/artemis-selector/src/main/java/org/apache/activemq/artemis/selector/filter/ComparisonExpression.java
index 7ed8a08..7419788 100755
--- 
a/artemis-selector/src/main/java/org/apache/activemq/artemis/selector/filter/ComparisonExpression.java
+++ 
b/artemis-selector/src/main/java/org/apache/activemq/artemis/selector/filter/ComparisonExpression.java
@@ -86,29 +86,14 @@ public abstract class ComparisonExpression extends 
BinaryExpression implements B
          regexp.append("\\A"); // The beginning of the input
          for (int i = 0; i < like.length(); i++) {
             char c = like.charAt(i);
-            if (escape == (0xFFFF & c)) {
+            if (escape == (0xFFFF & c) && shouldEscapeNext(like, i, c)) {
                i++;
-               if (i >= like.length()) {
-                  // nothing left to escape...
-                  break;
-               }
-
                char t = like.charAt(i);
                regexp.append("\\x");
                regexp.append(Integer.toHexString(0xFFFF & t));
             }
-            else if (c == '%') {
-               regexp.append(".*?"); // Do a non-greedy match
-            }
-            else if (c == '_') {
-               regexp.append("."); // match one
-            }
-            else if (REGEXP_CONTROL_CHARS.contains(new Character(c))) {
-               regexp.append("\\x");
-               regexp.append(Integer.toHexString(0xFFFF & c));
-            }
             else {
-               regexp.append(c);
+               append(regexp, c);
             }
          }
          regexp.append("\\z"); // The end of the input
@@ -116,6 +101,31 @@ public abstract class ComparisonExpression extends 
BinaryExpression implements B
          likePattern = Pattern.compile(regexp.toString(), Pattern.DOTALL);
       }
 
+      private boolean shouldEscapeNext(String selector, int i, char escape) {
+         int next = i + 1;
+         if (next < selector.length()) {
+            final char c = selector.charAt(next);
+            return (c == '_' || c == '%' || c == escape);
+         }
+         return false;
+      }
+
+      private void append(StringBuffer regexp, char c) {
+         if (c == '%') {
+            regexp.append(".*?"); // Do a non-greedy match
+         }
+         else if (c == '_') {
+            regexp.append("."); // match one
+         }
+         else if (REGEXP_CONTROL_CHARS.contains(new Character(c))) {
+            regexp.append("\\x");
+            regexp.append(Integer.toHexString(0xFFFF & c));
+         }
+         else {
+            regexp.append(c);
+         }
+      }
+
       /**
        * @see org.apache.activemq.filter.UnaryExpression#getExpressionSymbol()
        */

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/a337df70/artemis-selector/src/test/java/org/apache/activemq/artemis/selector/SelectorTest.java
----------------------------------------------------------------------
diff --git 
a/artemis-selector/src/test/java/org/apache/activemq/artemis/selector/SelectorTest.java
 
b/artemis-selector/src/test/java/org/apache/activemq/artemis/selector/SelectorTest.java
index bfb67a7..223a0df 100755
--- 
a/artemis-selector/src/test/java/org/apache/activemq/artemis/selector/SelectorTest.java
+++ 
b/artemis-selector/src/test/java/org/apache/activemq/artemis/selector/SelectorTest.java
@@ -449,6 +449,22 @@ public class SelectorTest {
    }
 
    @Test
+   public void testSpecialEscapeLiteral() throws Exception {
+      MockMessage message = createMessage();
+      assertSelector(message, "foo LIKE '%_%' ESCAPE '%'", true);
+      assertSelector(message, "endingUnderScore LIKE '_D7xlJIQn$_' ESCAPE 
'$'", true);
+      assertSelector(message, "endingUnderScore LIKE '_D7xlJIQn__' ESCAPE 
'_'", true);
+      assertSelector(message, "endingUnderScore LIKE '%D7xlJIQn%_' ESCAPE 
'%'", true);
+      assertSelector(message, "endingUnderScore LIKE '%D7xlJIQn%'  ESCAPE 
'%'", true);
+
+      // literal '%' at the end, no match
+      assertSelector(message, "endingUnderScore LIKE '%D7xlJIQn%%'  ESCAPE 
'%'", false);
+
+      assertSelector(message, "endingUnderScore LIKE '_D7xlJIQn\\_' ESCAPE 
'\\'", true);
+      assertSelector(message, "endingUnderScore LIKE '%D7xlJIQn\\_' ESCAPE 
'\\'", true);
+   }
+
+   @Test
    public void testInvalidSelector() throws Exception {
       MockMessage message = createMessage();
       assertInvalidSelector(message, "3+5");
@@ -476,6 +492,7 @@ public class SelectorTest {
       message.setStringProperty("quote", "'In God We Trust'");
       message.setStringProperty("foo", "_foo");
       message.setStringProperty("punctuation", 
"!#$&()*+,-./:;<=>?@[\\]^`{|}~");
+      message.setStringProperty("endingUnderScore", "XD7xlJIQn_");
       message.setBooleanProperty("trueProp", true);
       message.setBooleanProperty("falseProp", false);
       return message;

Reply via email to