[Fb-contrib-commit] fb-contrib/src/com/mebigfatguy/fbcontrib/detect PartiallyConstructedObjectAccess
Brought to you by:
dbrosius
From: Dave B. <dbr...@us...> - 2005-09-20 02:28:50
|
Update of /cvsroot/fb-contrib/fb-contrib/src/com/mebigfatguy/fbcontrib/detect In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28847/src/com/mebigfatguy/fbcontrib/detect Added Files: PartiallyConstructedObjectAccess.java Log Message: Initial checkin: PCOA --- NEW FILE: PartiallyConstructedObjectAccess.java --- /* * fb-contrib - Auxilliary detectors for Java programs * Copyright (C) 2005 Dave Brosius * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.mebigfatguy.fbcontrib.detect; import org.apache.bcel.Constants; import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.Type; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.OpcodeStack; import edu.umd.cs.findbugs.ba.ClassContext; public class PartiallyConstructedObjectAccess extends BytecodeScanningDetector { private BugReporter bugReporter; private OpcodeStack stack; private boolean reportedCtor; public PartiallyConstructedObjectAccess(BugReporter bugReporter) { this.bugReporter = bugReporter; stack = new OpcodeStack(); } public Object clone() throws CloneNotSupportedException { return super.clone(); } public void visitClassContext(ClassContext classContext) { JavaClass cls = classContext.getJavaClass(); if ((cls.getAccessFlags() & Constants.ACC_FINAL) == 0) super.visitClassContext(classContext); } public void visitCode(Code obj) { stack.resetForMethodEntry(this); reportedCtor = false; if ("<init>".equals(getMethodName())) super.visitCode(obj); } public void sawOpcode(int seen) { if (reportedCtor) return; try { if ((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE)) { int parmCount = Type.getArgumentTypes(getSigConstantOperand()).length; if (stack.getStackDepth() > parmCount) { OpcodeStack.Item itm = stack.getStackItem(parmCount); if (itm.getRegisterNumber() == 0) { JavaClass cls = itm.getJavaClass(); if (cls != null) { Method m = findMethod(cls, getNameConstantOperand(), getSigConstantOperand()); if (m != null) { if ((m.getAccessFlags() & Constants.ACC_FINAL) == 0) { bugReporter.reportBug( new BugInstance(this, "PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS", NORMAL_PRIORITY) .addClass(this) .addMethod(this) .addSourceLine(this, getPC())); reportedCtor = true; } } } } } } } catch (ClassNotFoundException cnfe) { bugReporter.reportMissingClass(cnfe); } finally { stack.sawOpcode(this, seen); } } private Method findMethod(JavaClass cls, String methodName, String methodSig) { Method[] methods = cls.getMethods(); for (Method m : methods) { if (methodName.equals(m.getName()) && methodSig.equals(m.getSignature())) { return m; } } return null; } } |