⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findnullderef.java.mine

📁 A static analysis tool to find bugs in Java programs
💻 MINE
📖 第 1 页 / 共 3 页
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003-2005 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.BitSet;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Set;import java.util.SortedSet;import java.util.TreeSet;import org.apache.bcel.Constants;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.Method;import org.apache.bcel.generic.ATHROW;import org.apache.bcel.generic.ConstantPoolGen;import org.apache.bcel.generic.Instruction;import org.apache.bcel.generic.InstructionHandle;import org.apache.bcel.generic.InstructionTargeter;import org.apache.bcel.generic.InvokeInstruction;import org.apache.bcel.generic.MethodGen;import org.apache.bcel.generic.PUTFIELD;import org.apache.bcel.generic.ReturnInstruction;import edu.umd.cs.findbugs.BugAnnotation;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.Detector;import edu.umd.cs.findbugs.FieldAnnotation;import edu.umd.cs.findbugs.FindBugsAnalysisFeatures;import edu.umd.cs.findbugs.LocalVariableAnnotation;import edu.umd.cs.findbugs.SourceLineAnnotation;import edu.umd.cs.findbugs.SystemProperties;import edu.umd.cs.findbugs.annotations.NonNull;import edu.umd.cs.findbugs.ba.AnalysisContext;import edu.umd.cs.findbugs.ba.BasicBlock;import edu.umd.cs.findbugs.ba.CFG;import edu.umd.cs.findbugs.ba.CFGBuilderException;import edu.umd.cs.findbugs.ba.ClassContext;import edu.umd.cs.findbugs.ba.DataflowAnalysisException;import edu.umd.cs.findbugs.ba.DataflowValueChooser;import edu.umd.cs.findbugs.ba.Edge;import edu.umd.cs.findbugs.ba.Hierarchy;import edu.umd.cs.findbugs.ba.JavaClassAndMethod;import edu.umd.cs.findbugs.ba.Location;import edu.umd.cs.findbugs.ba.MissingClassException;import edu.umd.cs.findbugs.ba.NullnessAnnotation;import edu.umd.cs.findbugs.ba.NullnessAnnotationDatabase;import edu.umd.cs.findbugs.ba.SignatureConverter;import edu.umd.cs.findbugs.ba.XFactory;import edu.umd.cs.findbugs.ba.XField;import edu.umd.cs.findbugs.ba.XMethod;import edu.umd.cs.findbugs.ba.interproc.PropertyDatabase;import edu.umd.cs.findbugs.ba.npe.IsNullValue;import edu.umd.cs.findbugs.ba.npe.IsNullValueDataflow;import edu.umd.cs.findbugs.ba.npe.IsNullValueFrame;import edu.umd.cs.findbugs.ba.npe.NullDerefAndRedundantComparisonCollector;import edu.umd.cs.findbugs.ba.npe.NullDerefAndRedundantComparisonFinder;import edu.umd.cs.findbugs.ba.npe.ParameterNullnessProperty;import edu.umd.cs.findbugs.ba.npe.ParameterNullnessPropertyDatabase;import edu.umd.cs.findbugs.ba.npe.RedundantBranch;import edu.umd.cs.findbugs.ba.npe.UsagesRequiringNonNullValues;import edu.umd.cs.findbugs.ba.type.TypeDataflow;import edu.umd.cs.findbugs.ba.type.TypeFrame;import edu.umd.cs.findbugs.ba.vna.AvailableLoad;import edu.umd.cs.findbugs.ba.vna.ValueNumber;import edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow;import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;import edu.umd.cs.findbugs.props.GeneralWarningProperty;import edu.umd.cs.findbugs.props.WarningPropertySet;import edu.umd.cs.findbugs.props.WarningPropertyUtil;import edu.umd.cs.findbugs.visitclass.Util;/** * A Detector to find instructions where a NullPointerException * might be raised.  We also look for useless reference comparisons * involving null and non-null values. * * @author David Hovemeyer * @author William Pugh * @see edu.umd.cs.findbugs.ba.npe.IsNullValueAnalysis */public class FindNullDeref		implements Detector, NullDerefAndRedundantComparisonCollector {	private static final boolean DEBUG = SystemProperties.getBoolean("fnd.debug");	private static final boolean DEBUG_NULLARG = SystemProperties.getBoolean("fnd.debug.nullarg");	private static final boolean DEBUG_NULLRETURN = SystemProperties.getBoolean("fnd.debug.nullreturn");	private static final boolean REPORT_SAFE_METHOD_TARGETS = true;	private static final String METHOD = SystemProperties.getProperty("fnd.method");	private static final String CLASS = SystemProperties.getProperty("fnd.class");		// Fields	private BugReporter bugReporter;		// Cached database stuff	private ParameterNullnessPropertyDatabase unconditionalDerefParamDatabase;	private boolean checkedDatabases = false;		// Transient state	private ClassContext classContext;	private Method method;	private IsNullValueDataflow invDataflow;	private BitSet previouslyDeadBlocks;	private NullnessAnnotation methodAnnotation;	public FindNullDeref(BugReporter bugReporter) {		this.bugReporter = bugReporter;	}	public void visitClassContext(ClassContext classContext) {		this.classContext = classContext;				String currentMethod = null;		JavaClass jclass = classContext.getJavaClass();		String className = jclass.getClassName();		if (CLASS != null && !className.equals(CLASS)) return;		Method[] methodList = jclass.getMethods();		for (Method method : methodList) {			try {				if (method.isAbstract() || method.isNative()						|| method.getCode() == null)					continue;								MethodGen mg = classContext.getMethodGen(method);				if (mg == null) {					continue;				}				currentMethod = SignatureConverter.convertMethodSignature(mg);				if (METHOD != null && !method.getName().equals(METHOD))					continue;				if (DEBUG)					System.out							.println("Checking for NP in " + currentMethod);				analyzeMethod(classContext, method);			} catch (MissingClassException e) {				bugReporter.reportMissingClass(e.getClassNotFoundException());			} catch (DataflowAnalysisException e) {				bugReporter.logError("While analyzing " + currentMethod + ": FindNullDeref caught dae exception", e);			} catch (CFGBuilderException e) {				bugReporter.logError("While analyzing " + currentMethod + ": FindNullDeref caught cfgb exception", e);			}		}	}	private void analyzeMethod(ClassContext classContext, Method method)	        throws CFGBuilderException, DataflowAnalysisException {		if (DEBUG || DEBUG_NULLARG)			System.out.println("Pre FND ");		MethodGen methodGen = classContext.getMethodGen(method);		if (methodGen == null)			return;		if (!checkedDatabases) {			checkDatabases();			checkedDatabases = true;		}		        // UsagesRequiringNonNullValues uses = classContext.getUsagesRequiringNonNullValues(method);		this.method = method;		this.methodAnnotation = getMethodNullnessAnnotation();		if (DEBUG || DEBUG_NULLARG)			System.out.println("FND: " + SignatureConverter.convertMethodSignature(methodGen));		this.previouslyDeadBlocks = findPreviouslyDeadBlocks();				// Get the IsNullValueDataflow for the method from the ClassContext		invDataflow = classContext.getIsNullValueDataflow(method);				// Create a NullDerefAndRedundantComparisonFinder object to do the actual		// work.  It will call back to report null derefs and redundant null comparisons		// through the NullDerefAndRedundantComparisonCollector interface we implement.		NullDerefAndRedundantComparisonFinder worker = new NullDerefAndRedundantComparisonFinder(				classContext,				method,				this);		worker.execute();		checkCallSitesAndReturnInstructions();			}	/**	 * Find set of blocks which were known to be dead before doing the	 * null pointer analysis.	 * 	 * @return set of previously dead blocks, indexed by block id	 * @throws CFGBuilderException 	 * @throws DataflowAnalysisException 	 */	private BitSet findPreviouslyDeadBlocks() throws DataflowAnalysisException, CFGBuilderException {		BitSet deadBlocks = new BitSet();		ValueNumberDataflow vnaDataflow = classContext.getValueNumberDataflow(method);		for (Iterator<BasicBlock> i = vnaDataflow.getCFG().blockIterator(); i.hasNext();) {			BasicBlock block = i.next();			ValueNumberFrame vnaFrame = vnaDataflow.getStartFact(block);			if (vnaFrame.isTop()) {				deadBlocks.set(block.getId());			}		}				return deadBlocks;	}	/**	 * Check whether or not the various interprocedural databases we can	 * use exist and are nonempty.	 */	private void checkDatabases() {		AnalysisContext analysisContext = AnalysisContext.currentAnalysisContext();		unconditionalDerefParamDatabase = analysisContext.getUnconditionalDerefParamDatabase();		}	private<		DatabaseType extends PropertyDatabase<?,?>> boolean isDatabaseNonEmpty(DatabaseType database) {		return database != null && !database.isEmpty();	}	/**	 * See if the currently-visited method declares a @NonNull annotation,	 * or overrides a method which declares a @NonNull annotation.	 */	private NullnessAnnotation getMethodNullnessAnnotation() {				if (method.getSignature().indexOf(")L") >= 0 || method.getSignature().indexOf(")[") >= 0 ) {			if (DEBUG_NULLRETURN) {				System.out.println("Checking return annotation for " +						SignatureConverter.convertMethodSignature(classContext.getJavaClass(), method));			}						XMethod m = XFactory.createXMethod(classContext.getJavaClass(), method);			return AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase()			.getResolvedAnnotation(m, false);		}		return NullnessAnnotation.UNKNOWN_NULLNESS;	}	private void checkCallSitesAndReturnInstructions()			throws CFGBuilderException, DataflowAnalysisException {		ConstantPoolGen cpg = classContext.getConstantPoolGen();		TypeDataflow typeDataflow = classContext.getTypeDataflow(method);				for (Iterator<Location> i = classContext.getCFG(method).locationIterator(); i.hasNext();) {			Location location = i.next();			Instruction ins = location.getHandle().getInstruction();			try {				if (ins instanceof InvokeInstruction) {					examineCallSite(location, cpg, typeDataflow);				} else if (methodAnnotation == NullnessAnnotation.NONNULL && ins.getOpcode() == Constants.ARETURN) {					examineReturnInstruction(location);				} else if (ins instanceof PUTFIELD) {					examinePutfieldInstruction(location, (PUTFIELD) ins, cpg);				}			} catch (ClassNotFoundException e) {				bugReporter.reportMissingClass(e);			}		}	}	private void examineCallSite(			Location location,			ConstantPoolGen cpg,			TypeDataflow typeDataflow)			throws DataflowAnalysisException, CFGBuilderException, ClassNotFoundException {				InvokeInstruction invokeInstruction = (InvokeInstruction)			location.getHandle().getInstruction();						String methodName = invokeInstruction.getName(cpg);		String signature = invokeInstruction.getSignature(cpg);				// Don't check equals() calls.		// If an equals() call unconditionally dereferences the parameter,		// it is the fault of the method, not the caller.		if (methodName.equals("equals") && signature.equals("(Ljava/lang/Object;)Z"))			return;				int returnTypeStart = signature.indexOf(')');		if (returnTypeStart < 0)			return;		String paramList = signature.substring(0, returnTypeStart + 1);				if (paramList.equals("()") ||				(paramList.indexOf("L") < 0 && paramList.indexOf('[') < 0))			// Method takes no arguments, or takes no reference arguments			return;		// See if any null arguments are passed		IsNullValueFrame frame =			classContext.getIsNullValueDataflow(method).getFactAtLocation(location);		if (!frame.isValid())			return;		BitSet nullArgSet =              frame.getArgumentSet(invokeInstruction, cpg, new DataflowValueChooser<IsNullValue>() {			public boolean choose(IsNullValue value) {				// Only choose non-exception values.				// Values null on an exception path might be due to				// infeasible control flow.				return value.mightBeNull() && !value.isException() && !value.isReturnValue();			}		});		BitSet definitelyNullArgSet = frame.getArgumentSet(invokeInstruction, cpg, new DataflowValueChooser<IsNullValue>() {			public boolean choose(IsNullValue value) {				return value.isDefinitelyNull();			}		});        nullArgSet.and(definitelyNullArgSet);		if (nullArgSet.isEmpty())			return;		if (DEBUG_NULLARG) {			System.out.println("Null arguments passed: " + nullArgSet);			System.out.println("Frame is: " + frame);			System.out.println("# arguments: " + frame.getNumArguments(invokeInstruction, cpg));			XMethod xm = XFactory.createXMethod(invokeInstruction, cpg);			System.out.print("Signature: " + xm.getSignature());		}		        		if (unconditionalDerefParamDatabase != null) {			checkUnconditionallyDereferencedParam(location, cpg, typeDataflow, invokeInstruction, nullArgSet, definitelyNullArgSet);		}						if (DEBUG_NULLARG) {			System.out.println("Checking nonnull params");		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -