Skip to content

Commit

Permalink
Merge pull request #174 from /issues/173
Browse files Browse the repository at this point in the history
Add better reporting if ASM fails to parse a class with an unspecified RuntimeException
  • Loading branch information
uschindler authored Sep 2, 2020
2 parents 6770ffa + f9b80d9 commit 87125db
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/main/java/de/thetaphi/forbiddenapis/AsmUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.Pattern;

import org.objectweb.asm.ClassReader;
Expand Down Expand Up @@ -181,5 +182,13 @@ public static ClassReader readAndPatchClass(InputStream in) throws IOException {
if (false) patchClassMajorVersion(bytecode, Opcodes.V15 + 1, Opcodes.V15);
return new ClassReader(bytecode);
}

/** Returns true, if the given {@link RuntimeException} was caused by ASM's ClassReader */
public static boolean isExceptionInAsmClassReader(RuntimeException re) {
// Because of javac bugs some class files are broken and cause RuntimeExceptions like AIOOBE
// We analyze stack trace if this is caused by ASM's ClassReader and not our code:
final StackTraceElement[] stack = re.getStackTrace();
return stack.length > 0 && Objects.equals(ClassReader.class.getName(), stack[0].getClassName());
}

}
22 changes: 21 additions & 1 deletion src/main/java/de/thetaphi/forbiddenapis/Checker.java
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ public ClassSignature lookupRelatedClass(String internalName, String internalNam
}
} catch (IOException ioe) {
throw new RelatedClassLoadingException(ioe, Type.getObjectType(internalNameOrig).getClassName());
} catch (RuntimeException re) {
if (AsmUtils.isExceptionInAsmClassReader(re)) {
throw new RelatedClassLoadingException(re, Type.getObjectType(internalNameOrig).getClassName());
}
throw re;
}
}

Expand Down Expand Up @@ -419,8 +424,23 @@ private int checkClass(final ClassReader reader, Pattern suppressAnnotationsPatt
}
msg.append(": ").append(cause);
msg.append(" (while looking up details about referenced class '").append(rcle.getClassName()).append("')");
assert cause != null && (cause instanceof IOException || cause instanceof ClassNotFoundException);
assert cause != null && (cause instanceof IOException || cause instanceof ClassNotFoundException || cause instanceof RuntimeException);
throw new ForbiddenApiException(msg.toString(), cause);
} catch (RuntimeException re) {
if (AsmUtils.isExceptionInAsmClassReader(re)) {
final StringBuilder msg = new StringBuilder()
.append("Failed to parse class '")
.append(className)
.append('\'');
final String source = scanner.getSourceFile();
if (source != null) {
msg.append(" (").append(source).append(')');
}
msg.append(": ").append(re);
throw new ForbiddenApiException(msg.toString(), re);
}
// else rethrow (it's occuring in our code):
throw re;
}
final List<ForbiddenViolation> violations = scanner.getSortedViolations();
final Pattern splitter = Pattern.compile(Pattern.quote(ForbiddenViolation.SEPARATOR));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public RelatedClassLoadingException(IOException e, String className) {
this.className = className;
}

public RelatedClassLoadingException(RuntimeException e, String className) {
super(e);
this.className = className;
}

public Exception getException() {
return (Exception) getCause();
}
Expand Down

0 comments on commit 87125db

Please sign in to comment.