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

📄 findrefcomparison.java

📁 一个查找java程序里bug的程序的源代码,该程序本身也是java写的,对提高java编程水平很有用
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	static boolean sawStringIntern;	public void visitClassContext(ClassContext classContext) {		JavaClass jclass = classContext.getJavaClass();		Method[] methodList = jclass.getMethods();		sawStringIntern = false;		for (int i = 0; i < methodList.length; ++i) {			Method method = methodList[i];			MethodGen methodGen = classContext.getMethodGen(method);			if (methodGen == null)				continue;			// Prescreening - must have IF_ACMPEQ, IF_ACMPNE,			// or an invocation of an instance method			BitSet bytecodeSet = classContext.getBytecodeSet(method);			if (!bytecodeSet.intersects(prescreenSet))				continue;			if (DEBUG)				System.out.println("FindRefComparison: analyzing " +				        SignatureConverter.convertMethodSignature(methodGen));			try {				analyzeMethod(classContext, method);			} catch (CFGBuilderException e) {				bugReporter.logError(e.toString());			} catch (DataflowAnalysisException e) {				bugReporter.logError(e.toString());			}		}	}	private void analyzeMethod(ClassContext classContext, Method method)	        throws CFGBuilderException, DataflowAnalysisException {		boolean sawCallToEquals = false;		JavaClass jclass = classContext.getJavaClass();		ConstantPoolGen cpg = classContext.getConstantPoolGen();		MethodGen methodGen = classContext.getMethodGen(method);		// Report at most one String comparison per method.		// We report the first highest priority warning.		stringComparison = null;		refComparison = null;		CFG cfg = classContext.getCFG(method);		DepthFirstSearch dfs = classContext.getDepthFirstSearch(method);		ExceptionSetFactory exceptionSetFactory =		        classContext.getExceptionSetFactory(method);		// Perform type analysis using our special type merger		// (which handles String types specially, keeping track of		// which ones appear to be dynamically created)		RefComparisonTypeMerger typeMerger =		        new RefComparisonTypeMerger(bugReporter, exceptionSetFactory);		TypeFrameModelingVisitor visitor =		        new RefComparisonTypeFrameModelingVisitor(methodGen.getConstantPool(), bugReporter);		TypeAnalysis typeAnalysis =		        new TypeAnalysis(methodGen, cfg, dfs, typeMerger, visitor, bugReporter, exceptionSetFactory);		TypeDataflow typeDataflow = new TypeDataflow(cfg, typeAnalysis);		typeDataflow.execute();		for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {			Location location = i.next();			Instruction ins = location.getHandle().getInstruction();			short opcode = ins.getOpcode();			if (opcode == Constants.IF_ACMPEQ || opcode == Constants.IF_ACMPNE) {				checkRefComparison(location, jclass, methodGen, typeDataflow);			} else if (invokeInstanceSet.get(opcode)) {				InvokeInstruction inv = (InvokeInstruction) ins;				String methodName = inv.getMethodName(cpg);				String methodSig = inv.getSignature(cpg);				if ((methodName.equals("equals") && methodSig.equals("(Ljava/lang/Object;)Z"))				        || (methodName.equals("equalIgnoreCases") && methodSig.equals("(Ljava/lang/String;)Z"))) {					sawCallToEquals = true;					checkEqualsComparison(location, jclass, methodGen, typeDataflow);				}			}		}		// If a String reference comparison was found in the method,		// report it		if (stringComparison != null) {			if (sawCallToEquals &&			        stringComparison.getPriority() >= NORMAL_PRIORITY) {				// System.out.println("Reducing priority of " + stringComparison);				stringComparison.setPriority(1 + stringComparison.getPriority());			}			if (stringComparison.getPriority() >= NORMAL_PRIORITY			        && !(method.isPublic() ||			        method.isProtected())) {				// System.out.print("private/packed");				stringComparison.setPriority(1 + stringComparison.getPriority());			}			if (stringComparison.getPriority() <= LOW_PRIORITY) {				bugReporter.reportBug(stringComparison);			}		}		if (refComparison != null) {			if (false && sawCallToEquals) {				// System.out.println("Reducing priority of " + refComparison);				refComparison.setPriority(1 + refComparison.getPriority());			}			if (refComparison.getPriority() <= LOW_PRIORITY)				bugReporter.reportBug(refComparison);		}	}	private void checkRefComparison(Location location, JavaClass jclass, MethodGen methodGen,	                                TypeDataflow typeDataflow) throws DataflowAnalysisException {		InstructionHandle handle = location.getHandle();		TypeFrame frame = typeDataflow.getFactAtLocation(location);		if (frame.getStackDepth() < 2)			throw new DataflowAnalysisException("Stack underflow", methodGen, handle);		int numSlots = frame.getNumSlots();		Type lhsType = frame.getValue(numSlots - 1);		Type rhsType = frame.getValue(numSlots - 2);		if (lhsType instanceof ReferenceType && rhsType instanceof ReferenceType) {			String lhs = SignatureConverter.convert(lhsType.getSignature());			String rhs = SignatureConverter.convert(rhsType.getSignature());			if (!lhs.equals(rhs))				return;			if (lhs.equals("java.lang.String") && rhs.equals("java.lang.String")) {				if (DEBUG)					System.out.println("String/String comparison at " +					        handle);				// Compute the priority:				// - two static strings => do not report				// - dynamic string and anything => high				// - static string and unknown => medium				// - all other cases => low				int priority = NORMAL_PRIORITY;				// System.out.println("Compare " + lhsType + " == " + rhsType);				byte type1 = lhsType.getType();				byte type2 = rhsType.getType();				// T1 T2 result				// S  S  no-op				// D  ?  high				// ?  D  high				// S  ?  normal				// ?  S  normal				if (type1 == T_STATIC_STRING && type2 == T_STATIC_STRING)					priority = LOW_PRIORITY + 1;				else if (type1 == T_DYNAMIC_STRING || type2 == T_DYNAMIC_STRING)					priority = HIGH_PRIORITY;				else if (type1 == T_STATIC_STRING || type2 == T_STATIC_STRING)					priority = LOW_PRIORITY;				else if (sawStringIntern)					priority = LOW_PRIORITY;				if (priority <= LOW_PRIORITY) {					String sourceFile = jclass.getSourceFileName();					BugInstance instance =					        new BugInstance(this, "ES_COMPARING_STRINGS_WITH_EQ", priority)					        .addClassAndMethod(methodGen, sourceFile)					        .addSourceLine(methodGen, sourceFile, handle)					        .addClass("java.lang.String").describe("CLASS_REFTYPE");					if (REPORT_ALL_REF_COMPARISONS)						bugReporter.reportBug(instance);					else if (stringComparison == null || priority < stringComparison.getPriority())						stringComparison = instance;				}			} else if (suspiciousSet.contains(lhs) && suspiciousSet.contains(rhs)) {				String sourceFile = jclass.getSourceFileName();				BugInstance instance = new BugInstance(this, "RC_REF_COMPARISON", NORMAL_PRIORITY)				        .addClassAndMethod(methodGen, sourceFile)				        .addSourceLine(methodGen, sourceFile, handle)				        .addClass(lhs).describe("CLASS_REFTYPE");				if (REPORT_ALL_REF_COMPARISONS)					bugReporter.reportBug(instance);				else if (refComparison == null)					refComparison = instance;			}		}	}	private void checkEqualsComparison(Location location, JavaClass jclass, MethodGen methodGen,	                                   TypeDataflow typeDataflow) throws DataflowAnalysisException {		InstructionHandle handle = location.getHandle();		String sourceFile = jclass.getSourceFileName();		TypeFrame frame = typeDataflow.getFactAtLocation(location);		if (frame.getStackDepth() < 2)			throw new DataflowAnalysisException("Stack underflow", methodGen, handle);		int numSlots = frame.getNumSlots();		Type lhsType_ = frame.getValue(numSlots - 2);		Type rhsType_ = frame.getValue(numSlots - 1);		if (lhsType_.equals(rhsType_))			return;		// Ignore top and bottom values		if (lhsType_.getType() == T_TOP || lhsType_.getType() == T_BOTTOM		        || rhsType_.getType() == T_TOP || rhsType_.getType() == T_BOTTOM)			return;		if (!(lhsType_ instanceof ReferenceType) || !(rhsType_ instanceof ReferenceType)) {			if (rhsType_.getType() == T_NULL) {				// A literal null value was passed directly to equals().				bugReporter.reportBug(new BugInstance(this, "EC_NULL_ARG", NORMAL_PRIORITY)				        .addClassAndMethod(methodGen, sourceFile)				        .addSourceLine(methodGen, sourceFile, location.getHandle()));			} else if (lhsType_.getType() == T_NULL) {				// Hmm...in this case, equals() is being invoked on				// a literal null value.  This is really the				// purview of FindNullDeref.  So, we'll just do nothing.			} else {				bugReporter.logError("equals() used to compare non-object type(s) " +				        lhsType_ + " and " + rhsType_ +				        " in " +				        SignatureConverter.convertMethodSignature(methodGen) +				        " at " + location.getHandle());			}			return;		}		// For now, ignore the case where either reference is not		// of an object type.  (It could be either an array or null.)		if (!(lhsType_ instanceof ObjectType) || !(rhsType_ instanceof ObjectType))			return;		ObjectType lhsType = (ObjectType) lhsType_;		ObjectType rhsType = (ObjectType) rhsType_;		int priority = LOW_PRIORITY + 1;		String bugType = "EC_UNRELATED_TYPES";		// See if the types are related by inheritance.		try {			if (!Hierarchy.isSubtype(lhsType, rhsType) && !Hierarchy.isSubtype(rhsType, lhsType)) {				// We have unrelated types.				// If both types are interfaces, then it is conceivable that				// there are class types that implement both interfaces,				// so the comparision might be meaningful.  Classify such				// cases as medium.  Other cases are high priority.				if (lhsType.referencesInterfaceExact() && rhsType.referencesInterfaceExact()) {					// TODO: This would be a good place to assume a closed					// universe and look at subclasses.					priority = NORMAL_PRIORITY;					bugType = "EC_UNRELATED_INTERFACES";				} else {					// TODO: it is possible that an unknown subclass of					// the class type implements the interface.					// Again, a subclass search could answer this					// question if we had a closed universe.					priority = HIGH_PRIORITY;				}			}		} catch (ClassNotFoundException e) {			bugReporter.reportMissingClass(e);			return;		}		if (priority <= LOW_PRIORITY) {			bugReporter.reportBug(new BugInstance(this, bugType, priority)			        .addClassAndMethod(methodGen, sourceFile)			        .addSourceLine(methodGen, sourceFile, location.getHandle())			        .addClass(lhsType.getClassName()).describe("CLASS_REFTYPE")			        .addClass(rhsType.getClassName()).describe("CLASS_REFTYPE"));		}	}	public void report() {	}	public static void main(String[] argv) throws Exception {		if (argv.length != 1) {			System.err.println("Usage: " + FindRefComparison.class.getName() + " <class file>");			System.exit(1);		}		DataflowTestDriver<TypeFrame, TypeAnalysis> driver =		        new DataflowTestDriver<TypeFrame, TypeAnalysis>() {			        public Dataflow<TypeFrame, TypeAnalysis> createDataflow(ClassContext classContext, Method method)			                throws CFGBuilderException, DataflowAnalysisException {				        RepositoryLookupFailureCallback lookupFailureCallback =				                classContext.getLookupFailureCallback();				        MethodGen methodGen = classContext.getMethodGen(method);				        DepthFirstSearch dfs = classContext.getDepthFirstSearch(method);				        CFG cfg = classContext.getCFG(method);				        ExceptionSetFactory exceptionSetFactory = classContext.getExceptionSetFactory(method);				        TypeMerger typeMerger =				                new RefComparisonTypeMerger(lookupFailureCallback, exceptionSetFactory);				        TypeFrameModelingVisitor visitor =				                new RefComparisonTypeFrameModelingVisitor(methodGen.getConstantPool(), lookupFailureCallback);				        TypeAnalysis analysis = new TypeAnalysis(methodGen, cfg, dfs, typeMerger, visitor,				                lookupFailureCallback, exceptionSetFactory);				        Dataflow<TypeFrame, TypeAnalysis> dataflow =				                new Dataflow<TypeFrame, TypeAnalysis>(cfg, analysis);				        dataflow.execute();				        return dataflow;			        }		        };		driver.execute(argv[0]);	}}// vim:ts=3

⌨️ 快捷键说明

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