[Fb-contrib-commit] SF.net SVN: fb-contrib: [924] trunk/fb-contrib/src/com/mebigfatguy/ fbcontrib/
Brought to you by:
dbrosius
From: <dbr...@us...> - 2007-10-07 22:38:42
|
Revision: 924 http://fb-contrib.svn.sourceforge.net/fb-contrib/?rev=924&view=rev Author: dbrosius Date: 2007-10-07 15:38:41 -0700 (Sun, 07 Oct 2007) Log Message: ----------- starting to find problems. Not yet differentiating severity of problems. Modified Paths: -------------- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ExceptionSoftening.java Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ExceptionSoftening.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ExceptionSoftening.java 2007-10-06 22:29:47 UTC (rev 923) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/ExceptionSoftening.java 2007-10-07 22:38:41 UTC (rev 924) @@ -20,18 +20,22 @@ import java.util.ArrayList; import java.util.BitSet; -import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; -import java.util.Set; +import java.util.ListIterator; +import java.util.Map; import org.apache.bcel.Constants; +import org.apache.bcel.Repository; import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.CodeException; import org.apache.bcel.classfile.ConstantClass; import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; +import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.OpcodeStack; @@ -47,10 +51,18 @@ */ public class ExceptionSoftening extends BytecodeScanningDetector { + private static JavaClass runtimeClass; + static { + try { + runtimeClass = Repository.lookupClass("java/lang/RuntimeException"); + } catch (ClassNotFoundException cnfe) { + runtimeClass = null; + } + } private BugReporter bugReporter; private OpcodeStack stack; - private LinkedHashMap<Integer, CodeException> catchHandlerPCs; - private Set<CatchInfo> catchInfos; + private Map<Integer, CodeException> catchHandlerPCs; + private List<CatchInfo> catchInfos; /** constructs a EXS detector given the reporter to report bugs on. @@ -68,8 +80,10 @@ @Override public void visitClassContext(ClassContext classContext) { try { - stack = new OpcodeStack(); - super.visitClassContext(classContext); + if (runtimeClass != null) { + stack = new OpcodeStack(); + super.visitClassContext(classContext); + } } finally { stack = null; } @@ -86,7 +100,7 @@ if (prescreen(method)) { stack.resetForMethodEntry(this); catchHandlerPCs = collectExceptions(obj.getExceptionTable()); - catchInfos = new HashSet<CatchInfo>(); + catchInfos = new ArrayList<CatchInfo>(); super.visitCode(obj); } } finally { @@ -103,8 +117,8 @@ public void sawOpcode(int seen) { try { stack.mergeJumps(this); - int nextPC = getNextPC(); - CodeException ex = catchHandlerPCs.get(Integer.valueOf(nextPC)); + int pc = getPC(); + CodeException ex = catchHandlerPCs.get(Integer.valueOf(pc)); if (ex != null) { int endPC; if ((seen == GOTO) || (seen == GOTO_W)) @@ -117,6 +131,30 @@ CatchInfo ci = new CatchInfo(ex.getHandlerPC(), endPC, catchSig); catchInfos.add(ci); } + + removeFinishedCatchBlocks(catchInfos, pc); + + if (seen == ATHROW) { + try { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + JavaClass exClass = itm.getJavaClass(); + if (exClass.instanceOf(runtimeClass)) { + if (catchInfos.size() > 0) { + String catchSignature = catchInfos.get(catchInfos.size() - 1).getSignature(); + + bugReporter.reportBug(new BugInstance(this, "EXS_EXCEPTION_SOFTENING_NO_CONSTRAINTS", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + } + } + } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); + } + } + } finally { stack.sawOpcode(this, seen); } @@ -127,7 +165,7 @@ * and with a catch type * * @param exceptions the exceptions from the class file - * @return the filtered exceptions keyed by catch handler pc + * @return the filtered exceptions keyed by catch end pc */ private LinkedHashMap<Integer, CodeException> collectExceptions(CodeException[] exceptions) { List<CodeException> filteredEx = new ArrayList<CodeException>(); @@ -140,12 +178,27 @@ LinkedHashMap<Integer, CodeException> handlers = new LinkedHashMap<Integer, CodeException>(); for (CodeException ex : filteredEx) { - handlers.put(Integer.valueOf(ex.getHandlerPC()), ex); + handlers.put(Integer.valueOf(ex.getEndPC()), ex); } return handlers; } + /** remove catchinfo blocks from the map where the handler end is before the current pc + * + * @param handlers the exception handlers installed + * @param pc the current pc + */ + private void removeFinishedCatchBlocks(List<CatchInfo> catchInfos, int pc) + { + Iterator<CatchInfo> it = catchInfos.iterator(); + while (it.hasNext()) + { + if (it.next().getFinish() < pc) + it.remove(); + } + } + /** returns whether a method explicitly throws an exception * * @param method the currently parsed method This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |