in activemq-shiro/src/main/java/org/apache/activemq/shiro/authz/ActiveMQWildcardPermission.java [110:238]
protected boolean matches(String pattern, String value) {
char[] patArr = pattern.toCharArray();
char[] valArr = value.toCharArray();
int patIndex = 0;
int patEndIndex = patArr.length - 1;
int valIndex = 0;
int valEndIndex = valArr.length - 1;
char ch;
boolean patternContainsStar = false;
for (char patternChar : patArr) {
if (patternChar == '*') {
patternContainsStar = true;
break;
}
}
if (!patternContainsStar) {
// No '*'s, so we make a shortcut
if (patEndIndex != valEndIndex) {
return false; // Pattern and string do not have the same size
}
for (int i = 0; i <= patEndIndex; i++) {
ch = patArr[i];
if (ch != '?') {
if (ch != valArr[i]) {
return false;// Character mismatch
}
}
}
return true; // String matches against pattern
}
// Process characters before first star
while ((ch = patArr[patIndex]) != '*' && valIndex <= valEndIndex) {
if (ch != '?') {
if (ch != valArr[valIndex]) {
return false;// Character mismatch
}
}
patIndex++;
valIndex++;
}
if (valIndex > valEndIndex) {
// All characters in the value are used. Check if only '*'s remain
// in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIndex; i <= patEndIndex; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
// Process characters after last star
while ((ch = patArr[patEndIndex]) != '*' && valIndex <= valEndIndex) {
if (ch != '?') {
if (ch != valArr[valEndIndex]) {
return false;// Character mismatch
}
}
patEndIndex--;
valEndIndex--;
}
if (valIndex > valEndIndex) {
// All characters in the value are used. Check if only '*'s remain
// in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIndex; i <= patEndIndex; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
// process pattern between stars. patIndex and patEndIndex always point to a '*'.
while (patIndex != patEndIndex && valIndex <= valEndIndex) {
int innerPatternIndex = -1;
for (int i = patIndex + 1; i <= patEndIndex; i++) {
if (patArr[i] == '*') {
innerPatternIndex = i;
break;
}
}
if (innerPatternIndex == patIndex + 1) {
// Two stars next to each other, skip the first one.
patIndex++;
continue;
}
// Find the pattern between patIndex & innerPatternIndex in the value between
// valIndex and valEndIndex
int innerPatternLength = (innerPatternIndex - patIndex - 1);
int innerValueLength = (valEndIndex - valIndex + 1);
int foundIndex = -1;
innerValueLoop:
for (int i = 0; i <= innerValueLength - innerPatternLength; i++) {
for (int j = 0; j < innerPatternLength; j++) {
ch = patArr[patIndex + j + 1];
if (ch != '?') {
if (ch != valArr[valIndex + i + j]) {
continue innerValueLoop;
}
}
}
foundIndex = valIndex + i;
break;
}
if (foundIndex == -1) {
return false;
}
patIndex = innerPatternIndex;
valIndex = foundIndex + innerPatternLength;
}
// All characters in the string are used. Check if only '*'s are left
// in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIndex; i <= patEndIndex; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}