import edu.umd.cs.findbugs.*;
import java.util.*;
import org.apache.bcel.classfile.Code;
public class CursorDetector extends BytecodeScanningDetector {
private BugReporter bugReporter;
int registerOnStack;
boolean isCursorReferenced;
boolean openCursor;
Hashtable
public CursorDetector(BugReporter bugReporter) {
this.bugReporter = bugReporter;
hs = new Hashtable
}
public void visit(Code code) {
registerOnStack = -1;
isCursorReferenced = false;
openCursor = false;
hs.clear();
super.visit(code);
if (!hs.isEmpty()) {
Enumeration e = hs.keys();
Object obj;
while (e.hasMoreElements()) {
obj = e.nextElement();
bugReporter.reportBug(
new BugInstance("CURSOR_NOT_CLOSED", HIGH_PRIORITY)
.addClassAndMethod(this).addSourceLine(this,((Integer)hs.get(obj)).intValue()));
}
hs.clear();
}
}
public void sawOpcode(int seen) {
if (isCursorReferenced) {
checkIfCloseCursorIsCalled(seen);
isCursorReferenced = false;
return;
}
else
if (seen == INVOKEVIRTUAL &&
"MyClass".equals(getClassConstantOperand())
&& "openCursor".equals(getNameConstantOperand()) ) {
openCursor = true;
return;
}
else
if (openCursor ) {
saveToLocalVariable(seen);
openCursor = false;
return;
}
else
if (!hs.isEmpty() && seen >= ALOAD && seen <= ALOAD_3 ) {
registerOnStack = (seen == ALOAD)? getRegisterOperand(): seen - ALOAD_0;
if (hs.containsKey(new Integer(registerOnStack)))
isCursorReferenced = true;
return;
}
else {
return;
}
}
void checkIfCloseCursorIsCalled(int seen) {
if (seen == INVOKEVIRTUAL &&
"MyClass".equals(getClassConstantOperand()) &&
"closeCursor".equals(getNameConstantOperand())
)
hs.remove(new Integer(registerOnStack)); //close cursoe
}
void saveToLocalVariable(int seen) {
switch (seen) {
case ASTORE_0:
hs.put(new Integer(0), new Integer(getPC()));
break;
case ASTORE_1:
hs.put(new Integer(1), new Integer(getPC()));
break;
case ASTORE_2:
hs.put(new Integer(2), new Integer(getPC()));
break;
case ASTORE_3:
hs.put(new Integer(3), new Integer(getPC()));
break;
case ASTORE:
hs.put(new Integer(getRegisterOperand()), new Integer(getPC()));
break;
}
// doesn't process if it is global variable.
}
}
No comments:
Post a Comment