[Fb-contrib-commit] SF.net SVN: fb-contrib: [591] trunk/fb-contrib/samples
Brought to you by:
dbrosius
|
From: <dbr...@us...> - 2006-08-08 05:06:48
|
Revision: 591 Author: dbrosius Date: 2006-08-07 22:06:38 -0700 (Mon, 07 Aug 2006) ViewCVS: http://svn.sourceforge.net/fb-contrib/?rev=591&view=rev Log Message: ----------- LEST is starting to work (with many false positives) Modified Paths: -------------- trunk/fb-contrib/samples/LEST_Sample.java trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java Modified: trunk/fb-contrib/samples/LEST_Sample.java =================================================================== --- trunk/fb-contrib/samples/LEST_Sample.java 2006-08-08 03:59:39 UTC (rev 590) +++ trunk/fb-contrib/samples/LEST_Sample.java 2006-08-08 05:06:38 UTC (rev 591) @@ -17,4 +17,17 @@ throw new IllegalArgumentException(pe.getMessage()); } } + + public Date testLest2(String input) + { + try + { + DateFormat df = new SimpleDateFormat("YYYY"); + return df.parse(input); + } + catch (ParseException pe) + { + throw new IllegalArgumentException(pe.getMessage(), pe); + } + } } Modified: trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java =================================================================== --- trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java 2006-08-08 03:59:39 UTC (rev 590) +++ trunk/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/LostExceptionStackTrace.java 2006-08-08 05:06:38 UTC (rev 591) @@ -19,13 +19,20 @@ package com.mebigfatguy.fbcontrib.detect; import java.util.BitSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; 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.ExceptionTable; +import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; +import com.mebigfatguy.fbcontrib.utils.RegisterUtils; + +import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.OpcodeStack; @@ -38,8 +45,19 @@ */ public class LostExceptionStackTrace extends BytecodeScanningDetector { + private static JavaClass exceptionClass; + static { + try { + exceptionClass = Repository.lookupClass("java/lang/Exception"); + } catch (ClassNotFoundException cnfe) { + exceptionClass = null; + } + } + private BugReporter bugReporter; private OpcodeStack stack; + private CodeException[] exceptions; + private Set<CatchInfo> catchInfos; /** * constructs a LEST detector given the reporter to report bugs on @@ -59,12 +77,15 @@ public void visitClassContext(ClassContext classContext) { try { int majorVersion = classContext.getJavaClass().getMajor(); - if (majorVersion >= Constants.MAJOR_1_4) { + if ((exceptionClass != null) && (majorVersion >= Constants.MAJOR_1_4)) { stack = new OpcodeStack(); + catchInfos = new HashSet<CatchInfo>(); super.visitClassContext(classContext); } } finally { stack = null; + catchInfos = null; + exceptions = null; } } @@ -93,6 +114,7 @@ public void visitCode(Code obj) { if (prescreen(obj, getMethod())) { stack.resetForMethodEntry(this); + exceptions = obj.getExceptionTable(); super.visitCode(obj); } } @@ -103,12 +125,107 @@ */ @Override public void sawOpcode(int seen) { + boolean markAsValid = false; + try { stack.mergeJumps(this); + int pc = getPC(); + for (CodeException ex : exceptions) { + if (pc == ex.getEndPC()) { + if ((seen >= IRETURN) && (seen <= RETURN)) { + addCatchBlock(ex.getHandlerPC(), Integer.MAX_VALUE); + } else if ((seen == GOTO) || (seen == GOTO_W)) + addCatchBlock(ex.getHandlerPC(), this.getBranchTarget()); + return; + } + } + Iterator<CatchInfo> it = catchInfos.iterator(); + while (it.hasNext()) { + try { + CatchInfo catchInfo = it.next(); + if (pc == catchInfo.getStart()) { + if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) { + catchInfo.setReg(RegisterUtils.getAStoreReg(this, seen)); + break; + } + } else if (pc > catchInfo.getFinish()) { + it.remove(); + break; + } else if ((pc > catchInfo.getStart()) && (pc <= catchInfo.getFinish())) { + if ((seen == INVOKESPECIAL) && ("<init>".equals(getNameConstantOperand()))) { + String className = getClassConstantOperand(); + JavaClass exClass = Repository.lookupClass(className); + if (exClass.instanceOf(exceptionClass)) { + String sig = getSigConstantOperand(); + if ((sig.indexOf("Exception") >= 0) + || (sig.indexOf("Throwable") >= 0)) { + markAsValid = true; + break; + } + } + } else if (seen == ATHROW) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + if ((itm.getRegisterNumber() != catchInfo.getRegister()) + && (itm.getUserValue() == null)) { + bugReporter.reportBug(new BugInstance(this, "LEST_LOST_EXCEPTION_STACK_TRACE", NORMAL_PRIORITY) + .addClass(this) + .addMethod(this) + .addSourceLine(this)); + it.remove(); + break; + } + } + } + } + } catch (ClassNotFoundException cnfe) { + bugReporter.reportMissingClass(cnfe); + it.remove(); + } + } } finally { stack.sawOpcode(this, seen); + if (markAsValid) { + if (stack.getStackDepth() > 0) { + OpcodeStack.Item itm = stack.getStackItem(0); + itm.setUserValue(Boolean.TRUE); + } + } } } + + private void addCatchBlock(int start, int finish) { + CatchInfo ci = new CatchInfo(start, finish); + catchInfos.add(ci); + } + + private static class CatchInfo { + private int catchStart; + private int catchFinish; + private int exReg; + + public CatchInfo(int start, int finish) { + catchStart = start; + catchFinish = finish; + exReg = -1; + } + + public void setReg(int reg) { + exReg = reg; + } + + public int getStart() { + return catchStart; + } + + public int getFinish() { + return catchFinish; + } + + public int getRegister() { + return exReg; + } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |