WW-5674 perf(ognl): match both allowlist package sets in one walk

isClassAllowlisted walked the class's package name twice, once for
ALLOWLIST_REQUIRED_PACKAGES and once for the configured allowlist. A two-set
overload probes both sets at each prefix, halving the work on a path that runs
for every OGNL member access.

Asserted equivalent to OR-ing the two single-set calls across a matrix of class
shapes and candidate sets.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lukasz Lenart
2026-08-03 13:12:27 +02:00
parent 8237a1fd8b
commit 34e5cf8b2a
2 changed files with 30 additions and 3 deletions
@@ -254,8 +254,7 @@ public class SecurityMemberAccess implements MemberAccess {
|| ALLOWLIST_REQUIRED_CLASSES.contains(clazz)
|| (providerAllowlist != null && providerAllowlist.getProviderAllowlist().contains(clazz))
|| (threadAllowlist != null && threadAllowlist.getAllowlist().contains(clazz))
|| isClassBelongsToPackages(clazz, ALLOWLIST_REQUIRED_PACKAGES)
|| isClassBelongsToPackages(clazz, allowlistPackageNames);
|| isClassBelongsToPackages(clazz, ALLOWLIST_REQUIRED_PACKAGES, allowlistPackageNames);
}
/**
@@ -391,7 +390,21 @@ public class SecurityMemberAccess implements MemberAccess {
}
public static boolean isClassBelongsToPackages(Class<?> clazz, Set<String> matchingPackages) {
return isPackageBelongsToPackages(toPackageName(clazz), matchingPackages, emptySet());
return isClassBelongsToPackages(clazz, matchingPackages, emptySet());
}
/**
* Tests the class's package against two sets in a single walk. Equivalent to calling
* {@link #isClassBelongsToPackages(Class, Set)} once per set and OR-ing the results, but
* walks the package name only once.
*
* @param clazz the class whose package is tested
* @param first the first set of package names to match against
* @param second the second set of package names to match against
* @return {@code true} if the class's package or any parent package is in either set
*/
public static boolean isClassBelongsToPackages(Class<?> clazz, Set<String> first, Set<String> second) {
return isPackageBelongsToPackages(toPackageName(clazz), first, second);
}
/**
@@ -195,4 +195,18 @@ public class SecurityMemberAccessPackageMatchingTest {
.isFalse();
}
}
@Test
public void twoSetOverloadEqualsDisjunctionOfSingleSetCalls() throws Exception {
for (Class<?> clazz : classShapes()) {
for (Set<String> first : CANDIDATE_SETS) {
for (Set<String> second : CANDIDATE_SETS) {
assertThat(isClassBelongsToPackages(clazz, first, second))
.as("clazz=[%s] first=%s second=%s", clazz.getName(), first, second)
.isEqualTo(isClassBelongsToPackages(clazz, first)
|| isClassBelongsToPackages(clazz, second));
}
}
}
}
}