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

📄 hierarchy.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			TypeFrame typeFrame,			ConstantPoolGen cpg) throws DataflowAnalysisException, ClassNotFoundException {		short opcode = invokeInstruction.getOpcode(); 		if (opcode == Constants.INVOKESTATIC) {			HashSet<JavaClassAndMethod> result = new HashSet<JavaClassAndMethod>();			JavaClassAndMethod targetMethod = findInvocationLeastUpperBound(invokeInstruction, cpg, CONCRETE_METHOD);			if (targetMethod != null) {				result.add(targetMethod);			}			return result;		}		if (!typeFrame.isValid()) {			return new HashSet<JavaClassAndMethod>();		}		Type receiverType;		boolean receiverTypeIsExact;		if (opcode == Constants.INVOKESPECIAL) {			// invokespecial instructions are dispatched to EXACTLY			// the class specified by the instruction			receiverType = ObjectTypeFactory.getInstance(invokeInstruction.getClassName(cpg));			receiverTypeIsExact = false; // Doesn't actually matter		} else {			// For invokevirtual and invokeinterface instructions, we have			// virtual dispatch.  By taking the receiver type (which may be a			// subtype of the class specified by the instruction),			// we may get a more precise set of call targets.			int instanceStackLocation = typeFrame.getInstanceStackLocation(invokeInstruction, cpg);			receiverType = typeFrame.getStackValue(instanceStackLocation);			if (!(receiverType instanceof ReferenceType)) {				return new HashSet<JavaClassAndMethod>();			}			receiverTypeIsExact = typeFrame.isExact(instanceStackLocation);		}		if (DEBUG_METHOD_LOOKUP) {			System.out.println("[receiver type is " + receiverType + ", " +					(receiverTypeIsExact ? "exact]" : " not exact]"));		}		return resolveMethodCallTargets((ReferenceType) receiverType, invokeInstruction, cpg, receiverTypeIsExact);	}	/**	 * Resolve possible instance method call targets.	 * Assumes that invokevirtual and invokeinterface methods may	 * call any subtype of the receiver class.	 * 	 * @param receiverType      type of the receiver object	 * @param invokeInstruction the InvokeInstruction	 * @param cpg               the ConstantPoolGen	 * @return Set of methods which might be called	 * @throws ClassNotFoundException	 */	public static Set<JavaClassAndMethod> resolveMethodCallTargets(			ReferenceType receiverType,			InvokeInstruction invokeInstruction,			ConstantPoolGen cpg			) throws ClassNotFoundException {		return resolveMethodCallTargets(receiverType, invokeInstruction, cpg, false);	}	/**	 * Resolve possible instance method call targets.	 * 	 * @param receiverType        type of the receiver object	 * @param invokeInstruction   the InvokeInstruction	 * @param cpg                 the ConstantPoolGen	 * @param receiverTypeIsExact if true, the receiver type is known exactly,	 *                            which should allow a precise result	 * @return Set of methods which might be called	 * @throws ClassNotFoundException	 */	public static Set<JavaClassAndMethod> resolveMethodCallTargets(			ReferenceType receiverType,			InvokeInstruction invokeInstruction,			ConstantPoolGen cpg,			boolean receiverTypeIsExact			) throws ClassNotFoundException {		HashSet<JavaClassAndMethod> result = new HashSet<JavaClassAndMethod>();		if (invokeInstruction.getOpcode() == Constants.INVOKESTATIC)			throw new IllegalArgumentException();		String methodName = invokeInstruction.getName(cpg);		String methodSig = invokeInstruction.getSignature(cpg);		// Array method calls aren't virtual.		// They should just resolve to Object methods.		if (receiverType instanceof ArrayType) {			JavaClass javaLangObject = AnalysisContext.currentAnalysisContext().lookupClass("java.lang.Object");			JavaClassAndMethod classAndMethod = findMethod(javaLangObject, methodName, methodSig, INSTANCE_METHOD);			if (classAndMethod != null)				result.add(classAndMethod);			return result;		}		AnalysisContext analysisContext = AnalysisContext.currentAnalysisContext();		// Get the receiver class.		JavaClass receiverClass = analysisContext.lookupClass(				((ObjectType) receiverType).getClassName());		// Figure out the upper bound for the method.		// This is what will be called if this is not a virtual call site.		JavaClassAndMethod upperBound = findMethod(receiverClass, methodName, methodSig, CONCRETE_METHOD);		if (upperBound == null) {			// Try superclasses			JavaClass[] superClassList = receiverClass.getSuperClasses();			upperBound = findMethod(superClassList, methodName, methodSig, CONCRETE_METHOD);		}		if (upperBound != null) {			if (DEBUG_METHOD_LOOKUP) {				System.out.println("Adding upper bound: " +						SignatureConverter.convertMethodSignature(upperBound.getJavaClass(), upperBound.getMethod()));			}			result.add(upperBound);		}		// Is this a virtual call site?		boolean virtualCall =			   invokeInstruction.getOpcode() != Constants.INVOKESPECIAL			&& !receiverTypeIsExact;		if (virtualCall) {			// This is a true virtual call: assume that any concrete			// subtype method may be called.			Set<JavaClass> subTypeSet = analysisContext.getSubtypes().getTransitiveSubtypes(receiverClass);			for (JavaClass subtype : subTypeSet) {				JavaClassAndMethod concreteSubtypeMethod = findMethod(subtype, methodName, methodSig, CONCRETE_METHOD);				if (concreteSubtypeMethod != null) {					result.add(concreteSubtypeMethod);				}			}		}		return result;	}//	//	/**//	 * Return whether or not the given method is concrete.//	 * //	 * @param xmethod the method//	 * @return true if the method is concrete, false otherwise//	 *///	public static boolean isConcrete(XMethod xmethod) {//		int accessFlags = xmethod.getAccessFlags();//		return (accessFlags & Constants.ACC_ABSTRACT) == 0//			&& (accessFlags & Constants.ACC_NATIVE) == 0;//	}	/**	 * Find a field with given name defined in given class.	 *	 * @param className the name of the class	 * @param fieldName the name of the field	 * @return the Field, or null if no such field could be found	 */	public static Field findField(String className, String fieldName) throws ClassNotFoundException {		JavaClass jclass = Repository.lookupClass(className);		while (jclass != null) {			Field[] fieldList = jclass.getFields();			for (Field field : fieldList) {				if (field.getName().equals(fieldName)) {					return field;				}			}			jclass = jclass.getSuperClass();		}		return null;	}/*	public static JavaClass findClassDefiningField(String className, String fieldName, String fieldSig)		throws ClassNotFoundException {		JavaClass jclass = Repository.lookupClass(className);		while (jclass != null) {			Field[] fieldList = jclass.getFields();			for (int i = 0; i < fieldList.length; ++i) {				Field field = fieldList[i];				if (field.getName().equals(fieldName) && field.getSignature().equals(fieldSig)) {					return jclass;				}			}			jclass = jclass.getSuperClass();		}		return null;	}*/	/**	 * Look up a field with given name and signature in given class,	 * returning it as an {@link XField XField} object.	 * If a field can't be found in the immediate class,	 * its superclass is search, and so forth.	 *	 * @param className name of the class through which the field	 *                  is referenced	 * @param fieldName name of the field	 * @param fieldSig  signature of the field	 * @return an XField object representing the field, or null if no such field could be found	 */	public static XField findXField(String className, String fieldName, String fieldSig)			throws ClassNotFoundException {		JavaClass classDefiningField = Repository.lookupClass(className);		Field field = null;		loop:			while (classDefiningField != null) {				Field[] fieldList = classDefiningField.getFields();				for (Field aFieldList : fieldList) {					field = aFieldList;					if (field.getName().equals(fieldName) && field.getSignature().equals(fieldSig)) {						break loop;					}				}				classDefiningField = classDefiningField.getSuperClass();			}		if (classDefiningField == null || field == null)			return null;		else {			String realClassName = classDefiningField.getClassName();			int accessFlags = field.getAccessFlags();			return field.isStatic()					? (XField) new StaticField(realClassName, fieldName, fieldSig, accessFlags)					: (XField) new InstanceField(realClassName, fieldName, fieldSig, accessFlags);		}	}	/**	 * Look up the field referenced by given FieldInstruction,	 * returning it as an {@link XField XField} object.	 *	 * @param fins the FieldInstruction	 * @param cpg  the ConstantPoolGen used by the class containing the instruction	 * @return an XField object representing the field, or null	 *         if no such field could be found	 */	public static XField findXField(FieldInstruction fins, @NonNull ConstantPoolGen cpg)			throws ClassNotFoundException {		String className = fins.getClassName(cpg);		String fieldName = fins.getFieldName(cpg);		String fieldSig = fins.getSignature(cpg);		XField xfield = findXField(className, fieldName, fieldSig);		short opcode = fins.getOpcode();		if (xfield != null &&				xfield.isStatic() == (opcode == Constants.GETSTATIC || opcode == Constants.PUTSTATIC))			return xfield;		else			return null;	}	/**	 * Determine whether the given INVOKESTATIC instruction	 * is an inner-class field accessor method.	 * @param inv the INVOKESTATIC instruction	 * @param cpg the ConstantPoolGen for the method	 * @return true if the instruction is an inner-class field accessor, false if not	 */	public static boolean isInnerClassAccess(INVOKESTATIC inv, ConstantPoolGen cpg) {		String methodName = inv.getName(cpg);		return methodName.startsWith("access$");	}	/**	 * Get the InnerClassAccess for access method called	 * by given INVOKESTATIC.	 * @param inv the INVOKESTATIC instruction	 * @param cpg the ConstantPoolGen for the method	 * @return the InnerClassAccess, or null if the instruction is not	 *    an inner-class access	 */	public static InnerClassAccess getInnerClassAccess(INVOKESTATIC inv, ConstantPoolGen cpg)			throws ClassNotFoundException {		String className = inv.getClassName(cpg);		String methodName = inv.getName(cpg);		String methodSig = inv.getSignature(cpg);		InnerClassAccess access = AnalysisContext.currentAnalysisContext()			.getInnerClassAccessMap().getInnerClassAccess(className, methodName);		return (access != null && access.getMethodSignature().equals(methodSig))			? access			: null;	}}// vim:ts=4

⌨️ 快捷键说明

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