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
This commit is contained in:
parent
1c782e0bc3
commit
a337df705e
|
@ -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()
|
||||
*/
|
||||
|
|
|
@ -448,6 +448,22 @@ public class SelectorTest {
|
|||
assertSelector(message, "punctuation LIKE '!#$&()*+,-./:;<=>?@[\\]^`{|}~'", true);
|
||||
}
|
||||
|
||||
@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();
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue