You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by gt...@apache.org on 2016/01/22 16:31:23 UTC

activemq git commit: https://issues.apache.org/jira/browse/AMQ-6137 - deal with 'special' escape chars in like selector expression

Repository: activemq
Updated Branches:
  refs/heads/master 4ee29c363 -> acbe31fcb


https://issues.apache.org/jira/browse/AMQ-6137 - deal with 'special' escape chars in like selector expression


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

Branch: refs/heads/master
Commit: acbe31fcb5d84c49c948a8816fd3a7cf50b58620
Parents: 4ee29c3
Author: gtully <ga...@gmail.com>
Authored: Fri Jan 22 15:29:42 2016 +0000
Committer: gtully <ga...@gmail.com>
Committed: Fri Jan 22 15:30:16 2016 +0000

----------------------------------------------------------------------
 .../activemq/filter/ComparisonExpression.java   | 38 ++++++++++++--------
 .../apache/activemq/selector/SelectorTest.java  | 17 +++++++++
 2 files changed, 41 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq/blob/acbe31fc/activemq-client/src/main/java/org/apache/activemq/filter/ComparisonExpression.java
----------------------------------------------------------------------
diff --git a/activemq-client/src/main/java/org/apache/activemq/filter/ComparisonExpression.java b/activemq-client/src/main/java/org/apache/activemq/filter/ComparisonExpression.java
index 62d53d1..4bb62de 100755
--- a/activemq-client/src/main/java/org/apache/activemq/filter/ComparisonExpression.java
+++ b/activemq-client/src/main/java/org/apache/activemq/filter/ComparisonExpression.java
@@ -88,25 +88,13 @@ 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
@@ -114,6 +102,28 @@ 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/blob/acbe31fc/activemq-unit-tests/src/test/java/org/apache/activemq/selector/SelectorTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/selector/SelectorTest.java b/activemq-unit-tests/src/test/java/org/apache/activemq/selector/SelectorTest.java
index 8279ae4..84a87b4 100755
--- a/activemq-unit-tests/src/test/java/org/apache/activemq/selector/SelectorTest.java
+++ b/activemq-unit-tests/src/test/java/org/apache/activemq/selector/SelectorTest.java
@@ -322,6 +322,21 @@ public class SelectorTest extends TestCase {
         assertSelector(message, "punctuation LIKE '!#$&()*+,-./:;<=>?@[\\]^`{|}~'", true);
     }
 
+    public void testSpecialEscapeLiteral() throws Exception {
+        Message 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);
+    }
+
     public void testInvalidSelector() throws Exception {
         Message message = createMessage();
         assertInvalidSelector(message, "3+5");
@@ -367,6 +382,8 @@ public class SelectorTest extends TestCase {
         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;