diff options
Diffstat (limited to 'icu4j/main/core/src/main/java/com/ibm/icu/text/CanonicalIterator.java')
-rw-r--r-- | icu4j/main/core/src/main/java/com/ibm/icu/text/CanonicalIterator.java | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/icu4j/main/core/src/main/java/com/ibm/icu/text/CanonicalIterator.java b/icu4j/main/core/src/main/java/com/ibm/icu/text/CanonicalIterator.java index 56b36d90c..39baae1b6 100644 --- a/icu4j/main/core/src/main/java/com/ibm/icu/text/CanonicalIterator.java +++ b/icu4j/main/core/src/main/java/com/ibm/icu/text/CanonicalIterator.java @@ -154,6 +154,10 @@ public final class CanonicalIterator { } } + // To avoid infinity loop caused by permute, we limit the depth of recursive + // call to permute and throw exception. + // We know in some unit test we need at least 4. Set to 8 just in case some + // unforseen use cases. /** * Simple implementation of permutation. * <br><b>Warning: The strings are not guaranteed to be in any particular order.</b> @@ -165,9 +169,27 @@ public final class CanonicalIterator { */ @Deprecated public static void permute(String source, boolean skipZeros, Set<String> output) { + permute(source, skipZeros, output, 0); + } + + private static int PERMUTE_DEPTH_LIMIT = 8; + /** + * Simple implementation of permutation. + * <br><b>Warning: The strings are not guaranteed to be in any particular order.</b> + * @param source the string to find permutations for + * @param skipZeros set to true to skip characters with canonical combining class zero + * @param output the set to add the results to + * @param depth the depth of the recursive call. + * @internal + * @deprecated This API is ICU internal only. + */ + @Deprecated + private static void permute(String source, boolean skipZeros, Set<String> output, int depth) { // TODO: optimize //if (PROGRESS) System.out.println("Permute: " + source); - + if (depth > PERMUTE_DEPTH_LIMIT) { + throw new UnsupportedOperationException("Stack too deep:" + depth); + } // optimization: // if zero or one character, just return a set with it // we check for length < 2 to keep from counting code points all the time @@ -193,7 +215,7 @@ public final class CanonicalIterator { // see what the permutations of the characters before and after this one are subpermute.clear(); permute(source.substring(0,i) - + source.substring(i + UTF16.getCharCount(cp)), skipZeros, subpermute); + + source.substring(i + UTF16.getCharCount(cp)), skipZeros, subpermute, depth+1); // prefix this character to all of them String chStr = UTF16.valueOf(source, i); |