Skip to content

Commit

Permalink
Race condition & memory leak in TypedFilter (#9925)
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick authored Nov 2, 2024
1 parent bec45d7 commit e0a54f4
Showing 1 changed file with 8 additions and 20 deletions.
28 changes: 8 additions & 20 deletions core/src/main/java/jenkins/security/stapler/TypedFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import hudson.ExtensionList;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.util.SystemProperties;
Expand All @@ -25,8 +23,6 @@
public class TypedFilter implements FieldRef.Filter, FunctionList.Filter {
private static final Logger LOGGER = Logger.getLogger(TypedFilter.class.getName());

private static final Map<Class<?>, Boolean> staplerCache = new HashMap<>();

private boolean isClassAcceptable(Class<?> clazz) {
if (clazz.isArray()) {
// special case to allow klass.isArray() dispatcher
Expand All @@ -46,31 +42,23 @@ private boolean isClassAcceptable(Class<?> clazz) {
return false;
}
}
return SKIP_TYPE_CHECK || isStaplerRelevantCached(clazz);
return SKIP_TYPE_CHECK || isStaplerRelevant.get(clazz);
}

private static boolean isStaplerRelevantCached(@NonNull Class<?> clazz) {
if (staplerCache.containsKey(clazz)) {
return staplerCache.get(clazz);
private static final ClassValue<Boolean> isStaplerRelevant = new ClassValue<>() {
@Override
protected Boolean computeValue(Class<?> clazz) {
return isSpecificClassStaplerRelevant(clazz) || isSuperTypesStaplerRelevant(clazz);
}
boolean ret = isStaplerRelevant(clazz);

staplerCache.put(clazz, ret);
return ret;
}

@Restricted(NoExternalUse.class)
public static boolean isStaplerRelevant(@NonNull Class<?> clazz) {
return isSpecificClassStaplerRelevant(clazz) || isSuperTypesStaplerRelevant(clazz);
}
};

private static boolean isSuperTypesStaplerRelevant(@NonNull Class<?> clazz) {
Class<?> superclass = clazz.getSuperclass();
if (superclass != null && isStaplerRelevantCached(superclass)) {
if (superclass != null && isStaplerRelevant.get(superclass)) {
return true;
}
for (Class<?> interfaceClass : clazz.getInterfaces()) {
if (isStaplerRelevantCached(interfaceClass)) {
if (isStaplerRelevant.get(interfaceClass)) {
return true;
}
}
Expand Down

0 comments on commit e0a54f4

Please sign in to comment.