Skip to content

Commit

Permalink
Prevent non-public classes of method params from breaking interceptor…
Browse files Browse the repository at this point in the history
… handling

Fixes: quarkusio#18477
  • Loading branch information
geoand committed Jul 7, 2021
1 parent 8975f5d commit 9518dc5
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,8 @@ private Map<MethodInfo, DecorationInfo> initDecoratedMethods() {

Map<MethodKey, DecorationInfo> candidates = new HashMap<>();
addDecoratedMethods(candidates, target.get().asClass(), bound,
new SubclassSkipPredicate(beanDeployment.getAssignabilityCheck()::isAssignableFrom));
new SubclassSkipPredicate(beanDeployment.getAssignabilityCheck()::isAssignableFrom,
beanDeployment.getBeanArchiveIndex()));

Map<MethodInfo, DecorationInfo> decoratedMethods = new HashMap<>(candidates.size());
for (Entry<MethodKey, DecorationInfo> entry : candidates.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ static Set<MethodInfo> addInterceptedMethodCandidates(BeanDeployment beanDeploym
boolean transformUnproxyableClasses) {
return addInterceptedMethodCandidates(beanDeployment, classInfo, candidates, classLevelBindings,
bytecodeTransformerConsumer, transformUnproxyableClasses,
new SubclassSkipPredicate(beanDeployment.getAssignabilityCheck()::isAssignableFrom), false);
new SubclassSkipPredicate(beanDeployment.getAssignabilityCheck()::isAssignableFrom,
beanDeployment.getBeanArchiveIndex()),
false);
}

static Set<MethodInfo> addInterceptedMethodCandidates(BeanDeployment beanDeployment, ClassInfo classInfo,
Expand Down Expand Up @@ -454,12 +456,14 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str
static class SubclassSkipPredicate implements Predicate<MethodInfo> {

private final BiFunction<Type, Type, Boolean> assignableFromFun;
private final IndexView beanArchiveIndex;
private ClassInfo clazz;
private List<MethodInfo> regularMethods;
private Set<MethodInfo> bridgeMethods = new HashSet<>();

public SubclassSkipPredicate(BiFunction<Type, Type, Boolean> assignableFromFun) {
public SubclassSkipPredicate(BiFunction<Type, Type, Boolean> assignableFromFun, IndexView beanArchiveIndex) {
this.assignableFromFun = assignableFromFun;
this.beanArchiveIndex = beanArchiveIndex;
}

void startProcessing(ClassInfo clazz) {
Expand Down Expand Up @@ -505,6 +509,20 @@ public boolean test(MethodInfo method) {
// Do not skip default methods - public non-abstract instance methods declared in an interface
return false;
}

List<Type> parameters = method.parameters();
if (!parameters.isEmpty() && (beanArchiveIndex != null)) {
for (Type type : parameters) {
ClassInfo parameterClassInfo = beanArchiveIndex.getClassByName(type.name());
if (parameterClassInfo == null) {
continue; // hope for the best
}
if (!Modifier.isPublic(parameterClassInfo.flags())) {
return true; // if the parameter is not public, we end up with IllegalAccessError when trying to access the use the load the class
}
}
}

// Note that we intentionally do not skip final methods here - these are handled later
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class SubclassSkipPredicateTest {
public void testPredicate() throws IOException {
IndexView index = Basics.index(Base.class, Submarine.class, Long.class, Number.class);
AssignabilityCheck assignabilityCheck = new AssignabilityCheck(index, null);
SubclassSkipPredicate predicate = new SubclassSkipPredicate(assignabilityCheck::isAssignableFrom);
SubclassSkipPredicate predicate = new SubclassSkipPredicate(assignabilityCheck::isAssignableFrom, null);

ClassInfo submarineClass = index.getClassByName(DotName.createSimple(Submarine.class.getName()));
predicate.startProcessing(submarineClass);
Expand Down

0 comments on commit 9518dc5

Please sign in to comment.