KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > detect > FindNonSerializableValuePassedToWriteObject


1 package edu.umd.cs.findbugs.detect;
2
3 import java.util.BitSet JavaDoc;
4 import java.util.Iterator JavaDoc;
5
6 import org.apache.bcel.Constants;
7 import org.apache.bcel.classfile.Method;
8 import org.apache.bcel.generic.ConstantPoolGen;
9 import org.apache.bcel.generic.Instruction;
10 import org.apache.bcel.generic.InstructionHandle;
11 import org.apache.bcel.generic.InvokeInstruction;
12 import org.apache.bcel.generic.MethodGen;
13 import org.apache.bcel.generic.ReferenceType;
14 import org.apache.bcel.generic.Type;
15
16 import edu.umd.cs.findbugs.DeepSubtypeAnalysis;
17 import edu.umd.cs.findbugs.BugInstance;
18 import edu.umd.cs.findbugs.BugReporter;
19 import edu.umd.cs.findbugs.Detector;
20 import edu.umd.cs.findbugs.SourceLineAnnotation;
21 import edu.umd.cs.findbugs.ba.CFG;
22 import edu.umd.cs.findbugs.ba.CFGBuilderException;
23 import edu.umd.cs.findbugs.ba.ClassContext;
24 import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
25 import edu.umd.cs.findbugs.ba.Location;
26 import edu.umd.cs.findbugs.ba.type.NullType;
27 import edu.umd.cs.findbugs.ba.type.TopType;
28 import edu.umd.cs.findbugs.ba.type.TypeDataflow;
29 import edu.umd.cs.findbugs.ba.type.TypeFrame;
30
31 public class FindNonSerializableValuePassedToWriteObject implements Detector {
32
33     private BugReporter bugReporter;
34
35     private static final boolean DEBUG = false;
36
37     public FindNonSerializableValuePassedToWriteObject(BugReporter bugReporter) {
38         this.bugReporter = bugReporter;
39     }
40
41     public void visitClassContext(ClassContext classContext) {
42         Method[] methodList = classContext.getJavaClass().getMethods();
43
44         for (Method method : methodList) {
45             if (method.getCode() == null)
46                 continue;
47
48             try {
49                 analyzeMethod(classContext, method);
50             } catch (CFGBuilderException e) {
51                 bugReporter.logError("Detector " + this.getClass().getName()
52                         + " caught exception", e);
53             } catch (DataflowAnalysisException e) {
54                 // bugReporter.logError("Detector " + this.getClass().getName() + " caught exception", e);
55
}
56         }
57     }
58
59     private void analyzeMethod(ClassContext classContext, Method method)
60             throws CFGBuilderException, DataflowAnalysisException {
61         MethodGen methodGen = classContext.getMethodGen(method);
62         if (methodGen == null)
63             return;
64         BitSet JavaDoc bytecodeSet = classContext.getBytecodeSet(method);
65         if (bytecodeSet == null) return;
66         // We don't adequately model instanceof interfaces yet
67
if (bytecodeSet.get(Constants.INSTANCEOF) || bytecodeSet.get(Constants.CHECKCAST))
68             return;
69         CFG cfg = classContext.getCFG(method);
70         TypeDataflow typeDataflow = classContext.getTypeDataflow(method);
71         ConstantPoolGen cpg = classContext.getConstantPoolGen();
72
73         String JavaDoc sourceFile = classContext.getJavaClass().getSourceFileName();
74         if (DEBUG) {
75             String JavaDoc methodName = methodGen.getClassName() + "."
76                     + methodGen.getName();
77             System.out.println("Checking " + methodName);
78         }
79
80         for (Iterator JavaDoc<Location> i = cfg.locationIterator(); i.hasNext();) {
81             Location location = i.next();
82             InstructionHandle handle = location.getHandle();
83             int pc = handle.getPosition();
84             Instruction ins = handle.getInstruction();
85
86             if (!(ins instanceof InvokeInstruction))
87                 continue;
88
89             InvokeInstruction invoke = (InvokeInstruction) ins;
90             String JavaDoc mName = invoke.getMethodName(cpg);
91             if (!mName.equals("writeObject"))
92                 continue;
93             String JavaDoc cName = invoke.getClassName(cpg);
94             if (!cName.equals("java.io.ObjectOutput")
95                     && !cName.equals("java.io.ObjectOutputStream"))
96                 continue;
97
98             TypeFrame frame = typeDataflow.getFactAtLocation(location);
99             if (!frame.isValid()) {
100                 // This basic block is probably dead
101
continue;
102             }
103             Type operandType = frame.getTopValue();
104
105             if (operandType.equals(TopType.instance())) {
106                 // unreachable
107
continue;
108             }
109             if (!(operandType instanceof ReferenceType)) {
110                 // Shouldn't happen - illegal bytecode
111
continue;
112             }
113             ReferenceType refType = (ReferenceType) operandType;
114
115             if (refType.equals(NullType.instance())) {
116                 continue;
117             }
118             String JavaDoc refSig = refType.getSignature();
119
120             try {
121
122                 double isSerializable = DeepSubtypeAnalysis.isDeepSerializable(refSig);
123                 
124                 if (isSerializable < 0.9) {
125                     double isRemote = DeepSubtypeAnalysis.isDeepRemote(refSig);
126                     if (isSerializable < isRemote)
127                         isSerializable = isRemote;
128                 }
129
130                 if (isSerializable < 0.9) {
131                     SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation
132                             .fromVisitedInstruction(classContext, methodGen,
133                                     sourceFile, handle);
134
135                     bugReporter
136                             .reportBug(new BugInstance(
137                                     this,
138                                     "DMI_NONSERIALIZABLE_OBJECT_WRITTEN",
139                                     isSerializable < 0.15 ? HIGH_PRIORITY
140                                             : isSerializable > 0.5 ? LOW_PRIORITY
141                                                     : NORMAL_PRIORITY)
142                                     .addClassAndMethod(methodGen, sourceFile)
143                                     .addClass(DeepSubtypeAnalysis.getComponentClass(refSig))
144                                     .addSourceLine(sourceLineAnnotation)
145                                     );
146                 }
147             } catch (ClassNotFoundException JavaDoc e) {
148                 // ignore
149
}
150         }
151     }
152
153     public void report() {
154     }
155
156 }
157
Popular Tags