mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 07:39:16 +00:00
ICU-22642 Avoid spending too much time inside CanonicalIterator
See #3017
This commit is contained in:
parent
6543634649
commit
87fce24233
2 changed files with 21 additions and 1 deletions
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ public final class CanonicalIterator {
|
|||
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>
|
||||
|
@ -308,6 +308,7 @@ public final class CanonicalIterator {
|
|||
}
|
||||
|
||||
|
||||
static private final int RESULT_LIMIT = 4096;
|
||||
private Set<String> getEquivalents2(String segment) {
|
||||
|
||||
Set<String> result = new HashSet<String>();
|
||||
|
@ -342,6 +343,12 @@ public final class CanonicalIterator {
|
|||
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;
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue