1 19 20 package soot.jimple.toolkits.base; 21 22 import soot.*; 23 import soot.jimple.*; 24 import soot.util.*; 25 import java.util.*; 26 import soot.jimple.toolkits.scalar.*; 27 import soot.tagkit.*; 28 29 public class ExceptionChecker extends BodyTransformer{ 30 31 FastHierarchy hierarchy; 32 ExceptionCheckerErrorReporter reporter; 33 34 public ExceptionChecker(ExceptionCheckerErrorReporter r){ 35 this.reporter = r; 36 } 37 38 protected void internalTransform(Body b, String phaseName, Map options){ 39 40 Iterator it = b.getUnits().iterator(); 41 while (it.hasNext()){ 42 Stmt s = (Stmt)it.next(); 43 if (s instanceof ThrowStmt){ 44 ThrowStmt ts = (ThrowStmt)s; 45 checkThrow(b, ts); 46 } 47 else if (s instanceof InvokeStmt){ 48 InvokeStmt is = (InvokeStmt)s; 49 checkInvoke(b, is); 50 } 51 else if ((s instanceof AssignStmt) && (((AssignStmt)s).getRightOp() instanceof InvokeExpr)){ 52 InvokeExpr ie = (InvokeExpr)((AssignStmt)s).getRightOp(); 53 checkInvokeExpr(b, ie, s); 54 } 55 } 56 } 57 58 protected void checkThrow(Body b, ThrowStmt ts){ 59 if (isThrowDeclared(b, ((RefType)ts.getOp().getType()).getSootClass()) || isThrowFromCompiler(ts) || isExceptionCaught(b, ts, (RefType)ts.getOp().getType())) return; 60 if (reporter != null){ 61 reporter.reportError(new ExceptionCheckerError(b.getMethod(), ((RefType)ts.getOp().getType()).getSootClass(), ts, (SourceLnPosTag)ts.getOpBox().getTag("SourceLnPosTag"))); 62 } 63 } 64 65 protected boolean isThrowDeclared(Body b, SootClass throwClass){ 69 if (hierarchy == null){ 70 hierarchy = new FastHierarchy(); 71 } 72 73 if (throwClass.equals(Scene.v().getSootClass("java.lang.RuntimeException")) || throwClass.equals(Scene.v().getSootClass("java.lang.Error"))) return true; 75 if (hierarchy.isSubclass(throwClass, Scene.v().getSootClass("java.lang.RuntimeException")) || hierarchy.isSubclass(throwClass, Scene.v().getSootClass("java.lang.Error"))) return true; 77 78 if (b.getMethod().throwsException(throwClass)) return true; 80 81 Iterator it = b.getMethod().getExceptions().iterator(); 83 while (it.hasNext()){ 84 SootClass nextEx = (SootClass)it.next(); 85 if (hierarchy.isSubclass(throwClass, nextEx)) return true; 86 } 87 return false; 88 } 89 90 protected boolean isThrowFromCompiler(ThrowStmt ts){ 92 if (ts.hasTag("ThrowCreatedByCompilerTag")) return true; 93 return false; 94 } 95 96 protected boolean isExceptionCaught(Body b, Stmt s, RefType throwType){ 98 if (hierarchy == null){ 99 hierarchy = new FastHierarchy(); 100 } 101 Iterator it = b.getTraps().iterator(); 102 while (it.hasNext()){ 103 Trap trap = (Trap)it.next(); 104 if (trap.getException().getType().equals(throwType) || hierarchy.isSubclass(throwType.getSootClass(), ((RefType)trap.getException().getType()).getSootClass())){ 105 if (isThrowInStmtRange(b, (Stmt)trap.getBeginUnit(), (Stmt)trap.getEndUnit(), s)) return true; 106 } 107 } 108 return false; 109 } 110 111 protected boolean isThrowInStmtRange(Body b, Stmt begin, Stmt end, Stmt s){ 112 Iterator it = b.getUnits().iterator(begin, end); 113 while (it.hasNext()){ 114 if (it.next().equals(s)) return true; 115 } 116 return false; 117 } 118 119 protected void checkInvoke(Body b, InvokeStmt is){ 120 checkInvokeExpr(b, is.getInvokeExpr(), is); 121 } 122 123 private List getExceptionSpec(SootClass intrface,NumberedString sig) { 131 if(intrface.declaresMethod(sig)) return intrface.getMethod(sig).getExceptions(); 132 List result=null; 133 SootClass obj=Scene.v().getSootClass("java.lang.Object"); 134 if(obj.declaresMethod(sig)) result=new Vector(obj.getMethod(sig).getExceptions()); 135 Iterator intrfacesit=intrface.getInterfaces().iterator(); 136 while(intrfacesit.hasNext()) { 137 SootClass suprintr=(SootClass) intrfacesit.next(); 138 List other=getExceptionSpec(suprintr,sig); 139 if(other!=null) 140 if(result==null) result=other; 141 else result.retainAll(other); 142 } 143 return result; 144 } 145 146 147 protected void checkInvokeExpr(Body b, InvokeExpr ie, Stmt s){ 148 if(ie instanceof InstanceInvokeExpr && 149 ((InstanceInvokeExpr) ie).getBase().getType() instanceof ArrayType && 150 ie.getMethodRef().name().equals("clone") && 151 ie.getMethodRef().parameterTypes().size()==0) 152 return; 157 List exceptions=ie instanceof InterfaceInvokeExpr 158 ? getExceptionSpec(ie.getMethodRef().declaringClass(), 163 ie.getMethodRef().getSubSignature()) 164 : ie.getMethod().getExceptions(); 166 Iterator it = exceptions.iterator(); 167 while (it.hasNext()){ 168 SootClass sc = (SootClass)it.next(); 169 if (isThrowDeclared(b, sc) || isExceptionCaught(b, s, sc.getType())) continue; 170 if (reporter != null){ 171 if (s instanceof InvokeStmt){ 172 reporter.reportError(new ExceptionCheckerError(b.getMethod(), sc, s, (SourceLnPosTag)s.getTag("SourceLnPosTag"))); 173 } 174 else if (s instanceof AssignStmt){ 175 reporter.reportError(new ExceptionCheckerError(b.getMethod(), sc, s, (SourceLnPosTag)((AssignStmt)s).getRightOpBox().getTag("SourceLnPosTag"))); 176 } 177 } 178 } 179 } 180 } 181 | Popular Tags |