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
|
regexp.append("\\A"); // The beginning of the input
|
||||||
for (int i = 0; i < like.length(); i++) {
|
for (int i = 0; i < like.length(); i++) {
|
||||||
char c = like.charAt(i);
|
char c = like.charAt(i);
|
||||||
if (escape == (0xFFFF & c)) {
|
if (escape == (0xFFFF & c) && shouldEscapeNext(like, i, c)) {
|
||||||
i++;
|
i++;
|
||||||
if (i >= like.length()) {
|
|
||||||
// nothing left to escape...
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
char t = like.charAt(i);
|
char t = like.charAt(i);
|
||||||
regexp.append("\\x");
|
regexp.append("\\x");
|
||||||
regexp.append(Integer.toHexString(0xFFFF & t));
|
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 {
|
else {
|
||||||
regexp.append(c);
|
append(regexp, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
regexp.append("\\z"); // The end of the input
|
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);
|
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()
|
* @see org.apache.activemq.filter.UnaryExpression#getExpressionSymbol()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -448,6 +448,22 @@ public class SelectorTest {
|
||||||
assertSelector(message, "punctuation LIKE '!#$&()*+,-./:;<=>?@[\\]^`{|}~'", true);
|
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
|
@Test
|
||||||
public void testInvalidSelector() throws Exception {
|
public void testInvalidSelector() throws Exception {
|
||||||
MockMessage message = createMessage();
|
MockMessage message = createMessage();
|
||||||
|
@ -476,6 +492,7 @@ public class SelectorTest {
|
||||||
message.setStringProperty("quote", "'In God We Trust'");
|
message.setStringProperty("quote", "'In God We Trust'");
|
||||||
message.setStringProperty("foo", "_foo");
|
message.setStringProperty("foo", "_foo");
|
||||||
message.setStringProperty("punctuation", "!#$&()*+,-./:;<=>?@[\\]^`{|}~");
|
message.setStringProperty("punctuation", "!#$&()*+,-./:;<=>?@[\\]^`{|}~");
|
||||||
|
message.setStringProperty("endingUnderScore", "XD7xlJIQn_");
|
||||||
message.setBooleanProperty("trueProp", true);
|
message.setBooleanProperty("trueProp", true);
|
||||||
message.setBooleanProperty("falseProp", false);
|
message.setBooleanProperty("falseProp", false);
|
||||||
return message;
|
return message;
|
||||||
|
|
Loading…
Reference in New Issue