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;
