Skip to content

Commit 87125db

Browse files
authored
Merge pull request #174 from /issues/173
Add better reporting if ASM fails to parse a class with an unspecified RuntimeException
2 parents 6770ffa + f9b80d9 commit 87125db

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

src/main/java/de/thetaphi/forbiddenapis/AsmUtils.java

+9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.nio.ByteBuffer;
2525
import java.nio.ByteOrder;
2626
import java.util.Locale;
27+
import java.util.Objects;
2728
import java.util.regex.Pattern;
2829

2930
import org.objectweb.asm.ClassReader;
@@ -181,5 +182,13 @@ public static ClassReader readAndPatchClass(InputStream in) throws IOException {
181182
if (false) patchClassMajorVersion(bytecode, Opcodes.V15 + 1, Opcodes.V15);
182183
return new ClassReader(bytecode);
183184
}
185+
186+
/** Returns true, if the given {@link RuntimeException} was caused by ASM's ClassReader */
187+
public static boolean isExceptionInAsmClassReader(RuntimeException re) {
188+
// Because of javac bugs some class files are broken and cause RuntimeExceptions like AIOOBE
189+
// We analyze stack trace if this is caused by ASM's ClassReader and not our code:
190+
final StackTraceElement[] stack = re.getStackTrace();
191+
return stack.length > 0 && Objects.equals(ClassReader.class.getName(), stack[0].getClassName());
192+
}
184193

185194
}

src/main/java/de/thetaphi/forbiddenapis/Checker.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ public ClassSignature lookupRelatedClass(String internalName, String internalNam
309309
}
310310
} catch (IOException ioe) {
311311
throw new RelatedClassLoadingException(ioe, Type.getObjectType(internalNameOrig).getClassName());
312+
} catch (RuntimeException re) {
313+
if (AsmUtils.isExceptionInAsmClassReader(re)) {
314+
throw new RelatedClassLoadingException(re, Type.getObjectType(internalNameOrig).getClassName());
315+
}
316+
throw re;
312317
}
313318
}
314319

@@ -419,8 +424,23 @@ private int checkClass(final ClassReader reader, Pattern suppressAnnotationsPatt
419424
}
420425
msg.append(": ").append(cause);
421426
msg.append(" (while looking up details about referenced class '").append(rcle.getClassName()).append("')");
422-
assert cause != null && (cause instanceof IOException || cause instanceof ClassNotFoundException);
427+
assert cause != null && (cause instanceof IOException || cause instanceof ClassNotFoundException || cause instanceof RuntimeException);
423428
throw new ForbiddenApiException(msg.toString(), cause);
429+
} catch (RuntimeException re) {
430+
if (AsmUtils.isExceptionInAsmClassReader(re)) {
431+
final StringBuilder msg = new StringBuilder()
432+
.append("Failed to parse class '")
433+
.append(className)
434+
.append('\'');
435+
final String source = scanner.getSourceFile();
436+
if (source != null) {
437+
msg.append(" (").append(source).append(')');
438+
}
439+
msg.append(": ").append(re);
440+
throw new ForbiddenApiException(msg.toString(), re);
441+
}
442+
// else rethrow (it's occuring in our code):
443+
throw re;
424444
}
425445
final List<ForbiddenViolation> violations = scanner.getSortedViolations();
426446
final Pattern splitter = Pattern.compile(Pattern.quote(ForbiddenViolation.SEPARATOR));

src/main/java/de/thetaphi/forbiddenapis/RelatedClassLoadingException.java

+5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public RelatedClassLoadingException(IOException e, String className) {
3333
this.className = className;
3434
}
3535

36+
public RelatedClassLoadingException(RuntimeException e, String className) {
37+
super(e);
38+
this.className = className;
39+
}
40+
3641
public Exception getException() {
3742
return (Exception) getCause();
3843
}

0 commit comments

Comments
 (0)