Package edu.umd.cs.findbugs.detect

Source Code of edu.umd.cs.findbugs.detect.InheritanceUnsafeGetResource

/*
* FindBugs - Find bugs in Java programs
* Copyright (C) 2004-2006 University of Maryland
*
* 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 edu.umd.cs.findbugs.detect;

import java.util.Set;

import org.apache.bcel.classfile.Constant;
import org.apache.bcel.classfile.ConstantClass;
import org.apache.bcel.classfile.ConstantString;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;

import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
import edu.umd.cs.findbugs.BytecodeScanningDetector;
import edu.umd.cs.findbugs.StatelessDetector;
import edu.umd.cs.findbugs.ba.AnalysisContext;
import edu.umd.cs.findbugs.ba.ch.Subtypes2;
import edu.umd.cs.findbugs.classfile.ClassDescriptor;

public class InheritanceUnsafeGetResource extends BytecodeScanningDetector implements StatelessDetector {

    private final BugReporter bugReporter;

    private boolean classIsFinal;

    // private boolean methodIsVisibleToOtherPackages;
    private boolean classIsVisibleToOtherPackages;

    // private boolean methodIsFinal;
    private boolean methodIsStatic;

    int state = 0;

    int sawGetClass;

    boolean reportedForThisClass;

    String stringConstant;

    int prevOpcode;

    public InheritanceUnsafeGetResource(BugReporter bugReporter) {
        this.bugReporter = bugReporter;
    }

    @Override
    public void visit(JavaClass obj) {
        classIsFinal = obj.isFinal();
        reportedForThisClass = false;
        classIsVisibleToOtherPackages = obj.isPublic() || obj.isProtected();
    }

    @Override
    public void visit(Method obj) {
        methodIsStatic = obj.isStatic();
        state = 0;
        sawGetClass = -100;
    }

    @Override
    public void sawOpcode(int seen) {
        if (reportedForThisClass) {
            return;
        }

        switch (seen) {
        case LDC:
            Constant constantValue = getConstantRefOperand();
            if (constantValue instanceof ConstantClass) {
                sawGetClass = -100;
            } else if (constantValue instanceof ConstantString) {
                stringConstant = ((ConstantString) constantValue).getBytes(getConstantPool());
            }
            break;

        case ALOAD_0:
            state = 1;
            break;
        case INVOKEVIRTUAL:
            if (getClassConstantOperand().equals("java/lang/Class")
                    && (getNameConstantOperand().equals("getResource") || getNameConstantOperand().equals("getResourceAsStream"))
                    && sawGetClass + 10 >= getPC()) {
                int priority = NORMAL_PRIORITY;
                if (prevOpcode == LDC && stringConstant != null && stringConstant.length() > 0 && stringConstant.charAt(0) == '/') {
                    priority = LOW_PRIORITY;
                } else {
                    priority = adjustPriority(priority);
                }
                bugReporter.reportBug(new BugInstance(this, "UI_INHERITANCE_UNSAFE_GETRESOURCE", priority)
                .addClassAndMethod(this).addSourceLine(this));
                reportedForThisClass = true;

            } else if (state == 1 && !methodIsStatic && !classIsFinal && classIsVisibleToOtherPackages
                    && getNameConstantOperand().equals("getClass") && getSigConstantOperand().equals("()Ljava/lang/Class;")) {
                sawGetClass = getPC();
            }
            state = 0;
            break;
        default:
            state = 0;
            break;
        }
        if (seen != LDC) {
            stringConstant = null;
        }
        prevOpcode = seen;

    }

    /**
     * Adjust the priority of a warning about to be reported.
     *
     * @param priority
     *            initial priority
     * @return adjusted priority
     */
    private int adjustPriority(int priority) {

        try {
            Subtypes2 subtypes2 = AnalysisContext.currentAnalysisContext().getSubtypes2();

            if (!subtypes2.hasSubtypes(getClassDescriptor())) {
                priority++;
            } else {
                Set<ClassDescriptor> mySubtypes = subtypes2.getSubtypes(getClassDescriptor());

                String myPackagename = getThisClass().getPackageName();

                for (ClassDescriptor c : mySubtypes) {
                    if (c.equals(getClassDescriptor())) {
                        continue;
                    }
                    if (!c.getPackageName().equals(myPackagename)) {
                        priority--;
                        break;
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            bugReporter.reportMissingClass(e);
        }
        return priority;
    }

}
TOP

Related Classes of edu.umd.cs.findbugs.detect.InheritanceUnsafeGetResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.