in src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java [498:554]
public void visitExceptionTable(final ExceptionTable obj) { // vmspec2 4.7.4
try {
// incorrectly named, it's the Exceptions attribute (vmspec2 4.7.4)
checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
final String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
if (!name.equals("Exceptions")) {
throw new ClassConstraintException(
"The Exceptions attribute '" + tostring(obj) + "' is not correctly named 'Exceptions' but '" + name + "'.");
}
final int[] excIndices = obj.getExceptionIndexTable();
for (final int excIndice : excIndices) {
checkIndex(obj, excIndice, CONST_Class);
final ConstantClass cc = (ConstantClass) cp.getConstant(excIndice);
checkIndex(cc, cc.getNameIndex(), CONST_Utf8); // can't be sure this ConstantClass has already been visited (checked)!
// convert internal notation on-the-fly to external notation:
final String cname = Utility.pathToPackage(((ConstantUtf8) cp.getConstant(cc.getNameIndex())).getBytes());
Verifier v = VerifierFactory.getVerifier(cname);
VerificationResult vr = v.doPass1();
if (vr != VerificationResult.VR_OK) {
throw new ClassConstraintException("Exceptions attribute '" + tostring(obj) + "' references '" + cname
+ "' as an Exception but it does not pass verification pass 1: " + vr);
}
// We cannot safely trust any other "instanceof" mechanism. We need to transitively verify
// the ancestor hierarchy.
JavaClass e = Repository.lookupClass(cname);
final JavaClass t = Repository.lookupClass(Type.THROWABLE.getClassName());
final JavaClass o = Repository.lookupClass(Type.OBJECT.getClassName());
while (e != o) {
if (e == t) {
break; // It's a subclass of Throwable, OKAY, leave.
}
v = VerifierFactory.getVerifier(e.getSuperclassName());
vr = v.doPass1();
if (vr != VerificationResult.VR_OK) {
throw new ClassConstraintException("Exceptions attribute '" + tostring(obj) + "' references '" + cname + "' as an Exception but '"
+ e.getSuperclassName() + "' in the ancestor hierachy does not pass verification pass 1: " + vr);
}
e = Repository.lookupClass(e.getSuperclassName());
}
if (e != t) {
throw new ClassConstraintException("Exceptions attribute '" + tostring(obj) + "' references '" + cname
+ "' as an Exception but it is not a subclass of '" + t.getClassName() + "'.");
}
}
} catch (final ClassNotFoundException e) {
// FIXME: this might not be the best way to handle missing classes.
throw new AssertionViolatedException("Missing class: " + e, e);
}
}