KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2003-2005 University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package edu.umd.cs.findbugs.detect;
21
22 import edu.umd.cs.findbugs.*;
23 import org.apache.bcel.Repository;
24 import org.apache.bcel.classfile.Method;
25
26 public class ReadReturnShouldBeChecked extends BytecodeScanningDetector
27         implements StatelessDetector {
28
29     boolean sawRead = false;
30
31     boolean sawSkip = false;
32
33     boolean recentCallToAvailable = false;
34
35     int sawAvailable = 0;
36
37     boolean wasBufferedInputStream = false;
38
39     private BugReporter bugReporter;
40
41     private int readPC, skipPC;
42
43     private String JavaDoc lastCallClass = null, lastCallMethod = null,
44             lastCallSig = null;
45
46     public ReadReturnShouldBeChecked(BugReporter bugReporter) {
47         this.bugReporter = bugReporter;
48     }
49
50     @Override JavaDoc
51     public void visit(Method obj) {
52         sawAvailable = 0;
53         sawRead = false;
54         sawSkip = false;
55         // check = (obj.getAccessFlags() & (ACC_PUBLIC | ACC_PROTECTED)) != 0;
56
}
57
58     private boolean isInputStream() {
59         try {
60         if (lastCallClass.startsWith("[")) return false;
61         return (Repository.instanceOf(lastCallClass,
62         "java.io.InputStream")
63         || Repository.implementationOf(lastCallClass,
64                 "java.io.DataInput") || Repository
65         .instanceOf(lastCallClass, "java.io.Reader"))
66         && !Repository.instanceOf(lastCallClass,
67                 "java.io.ByteArrayInputStream");
68         } catch (ClassNotFoundException JavaDoc e) {
69             return false;
70         }
71     }
72     
73     private boolean isBufferedInputStream() {
74         try {
75         if (lastCallClass.startsWith("[")) return false;
76         return Repository.instanceOf(
77                 lastCallClass,"java.io.BufferedInputStream");
78     } catch (ClassNotFoundException JavaDoc e) {
79         return false;
80     }
81     }
82     @Override JavaDoc
83     public void sawOpcode(int seen) {
84
85         if (seen == INVOKEVIRTUAL || seen == INVOKEINTERFACE) {
86             lastCallClass = getDottedClassConstantOperand();
87             lastCallMethod = getNameConstantOperand();
88             lastCallSig = getSigConstantOperand();
89         }
90
91         if (seen == INVOKEVIRTUAL || seen == INVOKEINTERFACE)
92             if (getNameConstantOperand().equals("available")
93                     && getSigConstantOperand().equals("()I")
94                     || getNameConstantOperand().startsWith("get")
95                     && getNameConstantOperand().endsWith("Length")
96                     && getSigConstantOperand().equals("()I")
97                     || getClassConstantOperand().equals("java/io/File")
98                     && getNameConstantOperand().equals("length")
99                     && getSigConstantOperand().equals("()J")) {
100                 sawAvailable = 70;
101                 return;
102             }
103         sawAvailable--;
104         if ((seen == INVOKEVIRTUAL || seen == INVOKEINTERFACE)
105                 && getNameConstantOperand().equals("read")
106
107                 && (getSigConstantOperand().equals("([B)I")
108                         || getSigConstantOperand().equals("([BII)I")
109                         || getSigConstantOperand().equals("([C)I") || getSigConstantOperand()
110                         .equals("([CII)I")) && isInputStream()) {
111             sawRead = true;
112             recentCallToAvailable = sawAvailable > 0;
113             readPC = getPC();
114             return;
115         }
116         if ((seen == INVOKEVIRTUAL || seen == INVOKEINTERFACE)
117                 && getNameConstantOperand().equals("skip")
118                 && getSigConstantOperand().equals("(J)J")
119                 && isInputStream() ) {
120             // if not ByteArrayInput Stream
121
// and either no recent calls to length
122
// or it is a BufferedInputStream
123

124             wasBufferedInputStream = isBufferedInputStream();
125             sawSkip = true;
126             recentCallToAvailable = sawAvailable > 0 && !wasBufferedInputStream;
127             skipPC = getPC();
128             return;
129
130         }
131
132         if ((seen == POP) || (seen == POP2)) {
133
134             if (sawRead) {
135                 bugReporter.reportBug(new BugInstance(this, "RR_NOT_CHECKED",
136                         recentCallToAvailable ? LOW_PRIORITY : NORMAL_PRIORITY)
137                         .addClassAndMethod(this).addCalledMethod(lastCallClass,
138                                 lastCallMethod, lastCallSig, false)
139                         .addSourceLine(this, readPC));
140             } else if (sawSkip) {
141
142                 bugReporter.reportBug(new BugInstance(this, "SR_NOT_CHECKED",
143                         (wasBufferedInputStream ? HIGH_PRIORITY
144                                 : recentCallToAvailable ? LOW_PRIORITY
145                                         : NORMAL_PRIORITY)).addClassAndMethod(
146                         this).addCalledMethod(lastCallClass, lastCallMethod,
147                         lastCallSig, false).addSourceLine(this, skipPC));
148             }
149         }
150         sawRead = false;
151         sawSkip = false;
152     }
153 }
154
Popular Tags