Skip to content

Commit

Permalink
ICU-22642 Avoid spending too much time inside CanonicalIterator
Browse files Browse the repository at this point in the history
See #3017
  • Loading branch information
FrankYFTang authored and roubert committed Jun 6, 2024
1 parent 6543634 commit 87fce24
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
13 changes: 13 additions & 0 deletions icu4c/source/common/caniter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@ UnicodeString* CanonicalIterator::getEquivalents(const UnicodeString &segment, i
char16_t USeg[256];
int32_t segLen = segment.extract(USeg, 256, status);
getEquivalents2(&basic, USeg, segLen, status);
if (U_FAILURE(status)) {
return nullptr;
}

// now get all the permutations
// add only the ones that are canonically equivalent
Expand Down Expand Up @@ -466,6 +469,9 @@ Hashtable *CanonicalIterator::getEquivalents2(Hashtable *fillinResult, const cha
Hashtable remainder(status);
remainder.setValueDeleter(uprv_deleteUObject);
if (extract(&remainder, cp2, segment, segLen, i, status) == nullptr) {
if (U_FAILURE(status)) {
return nullptr;
}
continue;
}

Expand All @@ -490,6 +496,13 @@ Hashtable *CanonicalIterator::getEquivalents2(Hashtable *fillinResult, const cha

ne = remainder.nextElement(el);
}
// ICU-22642 Guards against strings that have so many permutations
// that they would otherwise hang the function.
constexpr int32_t kResultLimit = 4096;
if (fillinResult->count() > kResultLimit) {
status = U_UNSUPPORTED_ERROR;
return nullptr;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public static void permute(String source, boolean skipZeros, Set<String> output)
permute(source, skipZeros, output, 0);
}

private static int PERMUTE_DEPTH_LIMIT = 8;
private static final int PERMUTE_DEPTH_LIMIT = 8;
/**
* Simple implementation of permutation.
* <br><b>Warning: The strings are not guaranteed to be in any particular order.</b>
Expand Down Expand Up @@ -308,6 +308,7 @@ private String[] getEquivalents(String segment) {
}


static private final int RESULT_LIMIT = 4096;
private Set<String> getEquivalents2(String segment) {

Set<String> result = new HashSet<String>();
Expand Down Expand Up @@ -342,6 +343,12 @@ private Set<String> getEquivalents2(String segment) {
result.add(prefix + item);
}
}

// ICU-22642 Guards against strings that have so many permutations
// that they would otherwise hang the function.
if (result.size() > RESULT_LIMIT) {
throw new UnsupportedOperationException("Too many permutations");
}
}
return result;
/*
Expand Down

0 comments on commit 87fce24

Please sign in to comment.