mirror of
https://github.com/apache/struts.git
synced 2026-08-06 07:06:58 +00:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user