diff --git a/WHATSNEW b/WHATSNEW index a8bb68085..1827e1010 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -4,6 +4,9 @@ Changes from current Ant 1.6.5 version to current RCS version Changes that could break older environments: -------------------------------------------- +* Improved recursion detection for lines with multiple matches of same token on one single line. + Bugzilla report 38456. + * Task will now log correctly even if no project is set. Bugzilla report 38458. diff --git a/src/main/org/apache/tools/ant/types/FilterSet.java b/src/main/org/apache/tools/ant/types/FilterSet.java index c15f7dafe..d2d4ac9db 100644 --- a/src/main/org/apache/tools/ant/types/FilterSet.java +++ b/src/main/org/apache/tools/ant/types/FilterSet.java @@ -179,6 +179,8 @@ public class FilterSet extends DataType implements Cloneable { private OnMissing onMissingFiltersFile = OnMissing.FAIL; private boolean readingFiles = false; + private int recurseDepth = 0; + /** * List of ordered filters and filter files. */ @@ -383,7 +385,6 @@ public class FilterSet extends DataType implements Cloneable { * @return The input string after token replacement. */ public synchronized String replaceTokens(String line) { - passedTokens = null; // reset for new line return iReplaceTokens(line); } @@ -506,7 +507,7 @@ public class FilterSet extends DataType implements Cloneable { String token = null; String value = null; - do { + while (index > -1) { //can't have zero-length token int endIndex = line.indexOf(endToken, index + beginToken.length() + 1); @@ -532,7 +533,8 @@ public class FilterSet extends DataType implements Cloneable { b.append(beginToken); i = index + beginToken.length(); } - } while ((index = line.indexOf(beginToken, i)) > -1); + index = line.indexOf(beginToken, i); + } b.append(line.substring(i)); return b.toString(); @@ -555,9 +557,10 @@ public class FilterSet extends DataType implements Cloneable { throws BuildException { String beginToken = getBeginToken(); String endToken = getEndToken(); - if (passedTokens == null) { + if (recurseDepth == 0) { passedTokens = new Vector(); } + recurseDepth++; if (passedTokens.contains(parent) && !duplicateToken) { duplicateToken = true; System.out.println( @@ -565,6 +568,7 @@ public class FilterSet extends DataType implements Cloneable { + passedTokens.toString() + "\nProblem token : " + beginToken + parent + endToken + " called from " + beginToken + passedTokens.lastElement().toString() + endToken); + recurseDepth--; return parent; } passedTokens.addElement(parent); @@ -582,6 +586,7 @@ public class FilterSet extends DataType implements Cloneable { } } } + recurseDepth--; return value; } diff --git a/src/testcases/org/apache/tools/ant/types/FilterSetTest.java b/src/testcases/org/apache/tools/ant/types/FilterSetTest.java index 8db916cf3..b68b719ff 100644 --- a/src/testcases/org/apache/tools/ant/types/FilterSetTest.java +++ b/src/testcases/org/apache/tools/ant/types/FilterSetTest.java @@ -113,6 +113,23 @@ public class FilterSetTest extends BuildFileTest { assertEquals(result, fs.replaceTokens(line)); } + public void testNonInfiniteRecursiveMultipleOnSingleLine() { + FilterSet filters = new FilterSet(); + + filters.setBeginToken("<"); + filters.setEndToken(">"); + + filters.addFilter("ul", ""); + filters.addFilter("/ul", ""); + filters.addFilter("li", ""); + filters.addFilter("/li", ""); + + String result = "Item 1 Item 2"; + String line = ""; + + assertEquals(result, filters.replaceTokens(line)); + } + public void testNestedFilterSets() { executeTarget("test-nested-filtersets");