Added characters to be escaped in file name patterns
Originally, characters could not be escaped in FileNameMatcher patterns. This breaks file name matching when escaped brackets "\[" and "\]" are used in the pattern. A fix has been implemented to allow for any character to be escaped by prepending it with a '\' Bug: 340715 Change-Id: Ie46fd211931fa09ef3a6a712bd1da3d7fb64c5e3 Signed-off-by: Gustav Karlsson <gustav.karlsson@tieto.com>
This commit is contained in:
parent
5d446f410d
commit
b3e9626743
|
@ -801,6 +801,46 @@ public void testUnsupportedGroupCase1() throws Exception {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEscapedBracket1() throws Exception {
|
||||||
|
assertMatch("\\[", "[", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEscapedBracket2() throws Exception {
|
||||||
|
assertMatch("\\[[a]", "[", false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEscapedBracket3() throws Exception {
|
||||||
|
assertMatch("\\[[a]", "a", false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEscapedBracket4() throws Exception {
|
||||||
|
assertMatch("\\[[a]", "[a", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEscapedBracket5() throws Exception {
|
||||||
|
assertMatch("[a\\]]", "]", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEscapedBracket6() throws Exception {
|
||||||
|
assertMatch("[a\\]]", "a", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEscapedBackslash() throws Exception {
|
||||||
|
assertMatch("a\\\\b", "a\\b", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultipleEscapedCharacters1() throws Exception {
|
||||||
|
assertMatch("\\]a?c\\*\\[d\\?\\]", "]abc*[d?]", true, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFilePathSimpleCase() throws Exception {
|
public void testFilePathSimpleCase() throws Exception {
|
||||||
assertFileNameMatch("a/b", "a/b", '/', true, false);
|
assertFileNameMatch("a/b", "a/b", '/', true, false);
|
||||||
|
|
|
@ -60,9 +60,9 @@
|
||||||
* <p>
|
* <p>
|
||||||
* Supported are the wildcard characters * and ? and groups with:
|
* Supported are the wildcard characters * and ? and groups with:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li> characters e.g. [abc]</li>
|
* <li>characters e.g. [abc]</li>
|
||||||
* <li> ranges e.g. [a-z]</li>
|
* <li>ranges e.g. [a-z]</li>
|
||||||
* <li> the following character classes
|
* <li>the following character classes
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>[:alnum:]</li>
|
* <li>[:alnum:]</li>
|
||||||
* <li>[:alpha:]</li>
|
* <li>[:alpha:]</li>
|
||||||
|
@ -78,9 +78,10 @@
|
||||||
* <li>[:word:]</li>
|
* <li>[:word:]</li>
|
||||||
* <li>[:xdigit:]</li>
|
* <li>[:xdigit:]</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* e. g. [[:xdigit:]] </li>
|
* e. g. [[:xdigit:]]</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </p>
|
* </p>
|
||||||
|
* Any character can be escaped by prepending it with a \
|
||||||
*/
|
*/
|
||||||
public class FileNameMatcher {
|
public class FileNameMatcher {
|
||||||
static final List<Head> EMPTY_HEAD_LIST = Collections.emptyList();
|
static final List<Head> EMPTY_HEAD_LIST = Collections.emptyList();
|
||||||
|
@ -199,7 +200,7 @@ private static int findGroupEnd(final int indexOfStartBracket,
|
||||||
int groupEnd = -1;
|
int groupEnd = -1;
|
||||||
while (groupEnd == -1) {
|
while (groupEnd == -1) {
|
||||||
|
|
||||||
final int possibleGroupEnd = pattern.indexOf(']',
|
final int possibleGroupEnd = indexOfUnescaped(pattern, ']',
|
||||||
firstValidEndBracketIndex);
|
firstValidEndBracketIndex);
|
||||||
if (possibleGroupEnd == -1)
|
if (possibleGroupEnd == -1)
|
||||||
throw new NoClosingBracketException(indexOfStartBracket, "[", //$NON-NLS-1$
|
throw new NoClosingBracketException(indexOfStartBracket, "[", //$NON-NLS-1$
|
||||||
|
@ -238,7 +239,7 @@ private static List<AbstractHead> parseHeads(final String pattern,
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
List<AbstractHead> heads = new ArrayList<AbstractHead>();
|
List<AbstractHead> heads = new ArrayList<AbstractHead>();
|
||||||
while (currentIndex < pattern.length()) {
|
while (currentIndex < pattern.length()) {
|
||||||
final int groupStart = pattern.indexOf('[', currentIndex);
|
final int groupStart = indexOfUnescaped(pattern, '[', currentIndex);
|
||||||
if (groupStart == -1) {
|
if (groupStart == -1) {
|
||||||
final String patternPart = pattern.substring(currentIndex);
|
final String patternPart = pattern.substring(currentIndex);
|
||||||
heads.addAll(createSimpleHeads(patternPart,
|
heads.addAll(createSimpleHeads(patternPart,
|
||||||
|
@ -264,24 +265,35 @@ private static List<AbstractHead> createSimpleHeads(
|
||||||
final String patternPart, final Character invalidWildgetCharacter) {
|
final String patternPart, final Character invalidWildgetCharacter) {
|
||||||
final List<AbstractHead> heads = new ArrayList<AbstractHead>(
|
final List<AbstractHead> heads = new ArrayList<AbstractHead>(
|
||||||
patternPart.length());
|
patternPart.length());
|
||||||
|
|
||||||
|
boolean escaped = false;
|
||||||
for (int i = 0; i < patternPart.length(); i++) {
|
for (int i = 0; i < patternPart.length(); i++) {
|
||||||
final char c = patternPart.charAt(i);
|
final char c = patternPart.charAt(i);
|
||||||
switch (c) {
|
if (escaped) {
|
||||||
case '*': {
|
|
||||||
final AbstractHead head = createWildCardHead(
|
|
||||||
invalidWildgetCharacter, true);
|
|
||||||
heads.add(head);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '?': {
|
|
||||||
final AbstractHead head = createWildCardHead(
|
|
||||||
invalidWildgetCharacter, false);
|
|
||||||
heads.add(head);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
final CharacterHead head = new CharacterHead(c);
|
final CharacterHead head = new CharacterHead(c);
|
||||||
heads.add(head);
|
heads.add(head);
|
||||||
|
escaped = false;
|
||||||
|
} else {
|
||||||
|
switch (c) {
|
||||||
|
case '*': {
|
||||||
|
final AbstractHead head = createWildCardHead(
|
||||||
|
invalidWildgetCharacter, true);
|
||||||
|
heads.add(head);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '?': {
|
||||||
|
final AbstractHead head = createWildCardHead(
|
||||||
|
invalidWildgetCharacter, false);
|
||||||
|
heads.add(head);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '\\':
|
||||||
|
escaped = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
final CharacterHead head = new CharacterHead(c);
|
||||||
|
heads.add(head);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return heads;
|
return heads;
|
||||||
|
@ -317,6 +329,18 @@ private void extendStringToMatchByOneCharacter(final char c) {
|
||||||
heads = newHeads;
|
heads = newHeads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int indexOfUnescaped(final String searchString,
|
||||||
|
final char ch, final int fromIndex) {
|
||||||
|
for (int i = fromIndex; i < searchString.length(); i++) {
|
||||||
|
char current = searchString.charAt(i);
|
||||||
|
if (current == ch)
|
||||||
|
return i;
|
||||||
|
if (current == '\\')
|
||||||
|
i++; // Skip the next char as it is escaped }
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param stringToMatch
|
* @param stringToMatch
|
||||||
|
|
Loading…
Reference in New Issue