Security: improve exact index matching performance (#36017)

This commit improves the efficiency of exact index name matching by
separating exact matches from those that include wildcards or regular
expressions. Internally, exact matching is done using a HashSet instead
of adding the exact matches to the automata. For the wildcard and
regular expression matches, the underlying implementation has not
changed.
This commit is contained in:
Jay Modi 2018-11-29 11:37:06 -07:00 committed by GitHub
parent 61c2db5ebb
commit ba3ee98943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 30 additions and 0 deletions

View File

@ -64,6 +64,36 @@ public final class IndicesPermission implements Iterable<IndicesPermission.Group
} }
static Predicate<String> indexMatcher(List<String> indices) { static Predicate<String> indexMatcher(List<String> indices) {
Set<String> exactMatch = new HashSet<>();
List<String> nonExactMatch = new ArrayList<>();
for (String indexPattern : indices) {
if (indexPattern.startsWith("/") || indexPattern.contains("*") || indexPattern.contains("?")) {
nonExactMatch.add(indexPattern);
} else {
exactMatch.add(indexPattern);
}
}
if (exactMatch.isEmpty() && nonExactMatch.isEmpty()) {
return s -> false;
} else if (exactMatch.isEmpty()) {
return buildAutomataPredicate(nonExactMatch);
} else if (nonExactMatch.isEmpty()) {
return buildExactMatchPredicate(exactMatch);
} else {
return buildExactMatchPredicate(exactMatch).or(buildAutomataPredicate(nonExactMatch));
}
}
private static Predicate<String> buildExactMatchPredicate(Set<String> indices) {
if (indices.size() == 1) {
final String singleValue = indices.iterator().next();
return singleValue::equals;
}
return indices::contains;
}
private static Predicate<String> buildAutomataPredicate(List<String> indices) {
try { try {
return Automatons.predicate(indices); return Automatons.predicate(indices);
} catch (TooComplexToDeterminizeException e) { } catch (TooComplexToDeterminizeException e) {