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

📄 unreadfields.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
				if (selfCall && getMethodName().equals("<init>")) {					sawSelfCallInConstructor = true;						if (DEBUG)						System.out.println("Saw self call in " + getFullyQualifiedMethodName()  + " to " + invokedClassName + "." + getNameConstantOperand()						);				}			}		}		if ((seen == IFNULL || seen == IFNONNULL) 			&& opcodeStack.getStackDepth() > 0)  {			OpcodeStack.Item item = opcodeStack.getStackItem(0);			XField f = item.getXField();			if (f != null) {				nullTested.add(f);				if (DEBUG)				System.out.println(f + " null checked in " +					getFullyQualifiedMethodName());				}			}		if (seen == GETFIELD || seen == INVOKEVIRTUAL 				|| seen == INVOKEINTERFACE				|| seen == INVOKESPECIAL || seen == PUTFIELD 				|| seen == IALOAD || seen == AALOAD || seen == BALOAD || seen == CALOAD || seen == SALOAD				|| seen == IASTORE || seen == AASTORE  || seen == BASTORE || seen == CASTORE || seen == SASTORE				|| seen == ARRAYLENGTH)  {			int pos = 0;			switch(seen) {			case ARRAYLENGTH:			case GETFIELD :				pos = 0;				break;			case INVOKEVIRTUAL :			case INVOKEINTERFACE:			case INVOKESPECIAL:				String sig = getSigConstantOperand();				pos = PreorderVisitor.getNumberArguments(sig);				break;			case PUTFIELD :			case IALOAD :			case AALOAD:			case BALOAD:			case CALOAD:			case SALOAD:				pos = 1;				break;			case IASTORE :			case AASTORE:			case BASTORE:			case CASTORE:			case SASTORE:				pos = 2;				break;			default: throw new RuntimeException("Impossible");			}			if (opcodeStack.getStackDepth() >= pos) {			OpcodeStack.Item item = opcodeStack.getStackItem(pos);			XField f = item.getXField();			if (DEBUG) System.out.println("RRR: " + f + " " + nullTested.contains(f)  + " " + writtenInConstructorFields.contains(f) + " " +  writtenNonNullFields.contains(f));			if (f != null && !nullTested.contains(f) 					&& ! (writtenInConstructorFields.contains(f)						 && writtenNonNullFields.contains(f))					) {				ProgramPoint p = new ProgramPoint(this);				HashSet <ProgramPoint> s = assumedNonNull.get(f);				if (s == null) {					s = new HashSet<ProgramPoint>();					assumedNonNull.put(f,s);					}				s.add(p);				if (DEBUG)				System.out.println(f + " assumed non-null in " +					getFullyQualifiedMethodName());				}			}			}		if (seen == ALOAD_1) {			count_aload_1++;		} else if (seen == GETFIELD || seen == GETSTATIC) {			XField f = XFactory.createReferencedXField(this);			pendingGetField = f;			if (getMethodName().equals("readResolve") 					&& seen == GETFIELD ) {				writtenFields.add(f);				writtenNonNullFields.add(f);			}			if (DEBUG) System.out.println("get: " + f);			// readFields.add(f);			if (!fieldAccess.containsKey(f))				fieldAccess.put(f, SourceLineAnnotation.fromVisitedInstruction(this));		} else if ((seen == PUTFIELD || seen == PUTSTATIC) && !selfAssignment) {			XField f = XFactory.createReferencedXField(this);			OpcodeStack.Item item = null;			if (opcodeStack.getStackDepth() > 0) {				item = opcodeStack.getStackItem(0);				if (!item.isNull()) nullTested.add(f);			}			writtenFields.add(f);			if (!fieldAccess.containsKey(f))				fieldAccess.put(f, SourceLineAnnotation.fromVisitedInstruction(this));			if (previousOpcode != ACONST_NULL || previousPreviousOpcode == GOTO )  {				writtenNonNullFields.add(f);				if (DEBUG) System.out.println("put nn: " + f);			}			else if (DEBUG) System.out.println("put: " + f);			if ( getMethod().isStatic() == f.isStatic() && (					calledFromConstructors.contains(getMethodName()+":"+getMethodSig())					|| getMethodName().equals("<init>") 					|| getMethodName().equals("init")  					|| getMethodName().equals("init")  					|| getMethodName().equals("initialize") 					|| getMethodName().equals("<clinit>") 					|| getMethod().isPrivate())) {				writtenInConstructorFields.add(f);				if (previousOpcode != ACONST_NULL || previousPreviousOpcode == GOTO ) 					assumedNonNull.remove(f);			} else {				writtenOutsideOfConstructorFields.add(f);			}		}		opcodeStack.sawOpcode(this, seen);		previousPreviousOpcode = previousOpcode;		previousOpcode = seen;		if (false && DEBUG) {		System.out.println("After " + OPCODE_NAMES[seen] + " opcode stack is");		System.out.println(opcodeStack);		}	}	static Pattern dontComplainAbout = Pattern.compile("class[$]");	static Pattern withinAnonymousClass = Pattern.compile("[$][0-9].*[$]");	@Override		 public void report() {		Set<String> fieldNamesSet = new HashSet<String>();		for(XField f : writtenNonNullFields)			fieldNamesSet.add(f.getName());		if (DEBUG) {			System.out.println("read fields:" );			for(XField f : readFields) 				System.out.println("  " + f);			if (!containerFields.isEmpty()) {				System.out.println("ejb3 fields:" );				for(XField f : containerFields) 					System.out.println("  " + f);			}			if (!reflectiveFields.isEmpty()) {				System.out.println("reflective fields:" );				for(XField f : reflectiveFields) 					System.out.println("  " + f);			}			System.out.println("written fields:" );			for (XField f : writtenFields) 				System.out.println("  " + f);			System.out.println("written nonnull fields:" );			for (XField f : writtenNonNullFields) 				System.out.println("  " + f);			System.out.println("assumed nonnull fields:" );			for (XField f : assumedNonNull.keySet()) 				System.out.println("  " + f);		}		// Don't report anything about ejb3Fields		declaredFields.removeAll(containerFields);		declaredFields.removeAll(reflectiveFields);		TreeSet<XField> notInitializedInConstructors =				new TreeSet<XField>(declaredFields);		notInitializedInConstructors.retainAll(readFields);		notInitializedInConstructors.retainAll(writtenFields);		notInitializedInConstructors.retainAll(assumedNonNull.keySet());		notInitializedInConstructors.removeAll(staticFields);		notInitializedInConstructors.removeAll(writtenInConstructorFields);		// notInitializedInConstructors.removeAll(staticFields);		TreeSet<XField> readOnlyFields =				new TreeSet<XField>(declaredFields);		readOnlyFields.removeAll(writtenFields);		readOnlyFields.retainAll(readFields);		TreeSet<XField> nullOnlyFields =			new TreeSet<XField>(declaredFields);		nullOnlyFields.removeAll(writtenNonNullFields);		nullOnlyFields.retainAll(readFields);		Set<XField> writeOnlyFields = declaredFields;		writeOnlyFields.removeAll(readFields);		Map<String, Integer> count = new HashMap<String, Integer>();		for (XField f : nullOnlyFields) {			int increment = 3;			Collection<ProgramPoint> assumedNonNullAt = assumedNonNull.get(f);			if (assumedNonNullAt != null)				increment += assumedNonNullAt.size();			for(String s : unknownAnnotation.get(f)) {				Integer value = count.get(s);				if (value == null) 					count.put(s,increment);				else count.put(s,value+increment);			}			}		Map<XField, Integer> maxCount = new HashMap<XField, Integer>();				LinkedList<XField> assumeReflective = new LinkedList<XField>();		for (XField f : nullOnlyFields) {			int myMaxCount = 0;			for(String s : unknownAnnotation.get(f)) {				Integer value = count.get(s);				if (value != null && myMaxCount < value) myMaxCount = value;			}			if (myMaxCount > 0)				maxCount.put(f, myMaxCount);			if (myMaxCount > 15)				assumeReflective.add(f);		}						readOnlyFields.removeAll(assumeReflective);		nullOnlyFields.removeAll(assumeReflective);		notInitializedInConstructors.removeAll(assumeReflective);				for (XField f : notInitializedInConstructors) {			String fieldName = f.getName();			String className = f.getClassName();			String fieldSignature = f.getSignature();			if (f.isResolved()					&& !fieldsOfNativeClasses.contains(f)					&& (fieldSignature.charAt(0) == 'L' || fieldSignature.charAt(0) == '[')					) {				int priority = LOW_PRIORITY;				if (assumedNonNull.containsKey(f)) 				  bugReporter.reportBug(new BugInstance(this,						"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR",						priority)						.addClass(className)						.addField(f));			}		}		for (XField f : readOnlyFields) {			String fieldName = f.getName();			String className = f.getClassName();			String fieldSignature = f.getSignature();			if (f.isResolved()					&& !fieldsOfNativeClasses.contains(f)) {				int priority = NORMAL_PRIORITY;				if (!(fieldSignature.charAt(0) == 'L' || fieldSignature.charAt(0) == '['))					priority++;				if (maxCount.containsKey(f)) priority++;				bugReporter.reportBug(addClassFieldAndAccess(new BugInstance(this,						"UWF_UNWRITTEN_FIELD",						priority),f));			}		}		for (XField f : nullOnlyFields) {			String fieldName = f.getName();			String className = f.getClassName();			String fieldSignature = f.getSignature();			if (DEBUG) {				System.out.println("Null only: " + f);				System.out.println("   : " + assumedNonNull.containsKey(f));				System.out.println("   : " + fieldsOfSerializableOrNativeClassed.contains(f));				System.out.println("   : " + fieldNamesSet.contains(f.getName()));				System.out.println("   : " + abstractClasses.contains(f.getClassName()));				System.out.println("   : " + hasNonAbstractSubClass.contains(f.getClassName()));				System.out.println("   : " + f.isResolved());			}			if (!f.isResolved()) continue;			if (fieldsOfNativeClasses.contains(f)) continue;			if (DEBUG) {				System.out.println("Ready to report");			}			int priority = NORMAL_PRIORITY;			if (maxCount.containsKey(f)) priority++;			if (abstractClasses.contains(f.getClassName())) {				priority++;				if (! hasNonAbstractSubClass.contains(f.getClassName())) priority++;			}			// if (fieldNamesSet.contains(f.getName())) priority++;			if (assumedNonNull.containsKey(f)) {				int npPriority = priority;							HashSet<ProgramPoint> assumedNonNullAt = assumedNonNull.get(f);				if (assumedNonNullAt.size() > 14) {					npPriority+=2;				} else if (assumedNonNullAt.size() > 6) {					npPriority++;				} else {					priority--;				}				for (ProgramPoint p : assumedNonNullAt)					bugReporter.reportBug(new BugInstance(this,							"NP_UNWRITTEN_FIELD",							npPriority)							.addClassAndMethod(p.method)							.addField(f)							.addSourceLine(p.sourceLine)					);			} else {				if (f.isStatic()) priority++;				if (finalFields.contains(f)) priority++;				if (fieldsOfSerializableOrNativeClassed.contains(f)) priority++;			}			if (!readOnlyFields.contains(f)) 				bugReporter.reportBug(						addClassFieldAndAccess(new BugInstance(this,"UWF_NULL_FIELD",priority), f).lowerPriorityIfDeprecated()					);		}		for (XField f : writeOnlyFields) {			String fieldName = f.getName();			String className = f.getClassName();			int lastDollar =					Math.max(className.lastIndexOf('$'),							className.lastIndexOf('+'));			boolean isAnonymousInnerClass =					(lastDollar > 0)							&& (lastDollar < className.length() - 1)							&& Character.isDigit(className.charAt(lastDollar+1));			if (DEBUG) {				System.out.println("Checking write only field " + className						+ "." + fieldName						+ "\t" + constantFields.contains(f)						+ "\t" + f.isStatic()				);			}			if (!f.isResolved()) continue;			if (dontComplainAbout.matcher(fieldName).find()) continue;			if (fieldName.startsWith("this$")					|| fieldName.startsWith("this+")) {				String outerClassName = className.substring(0, lastDollar);				try {					JavaClass outerClass = Repository.lookupClass(outerClassName);					if (classHasParameter(outerClass)) continue;				} catch (ClassNotFoundException e) {					bugReporter.reportMissingClass(e);				}				if (!innerClassCannotBeStatic.contains(className)) {					boolean easyChange = !needsOuterObjectInConstructor.contains(className);					if (easyChange || !isAnonymousInnerClass) {						// easyChange    isAnonymousInnerClass						// true          false			medium, SIC						// true          true				low, SIC_ANON						// false         true				not reported						// false         false			low, SIC_THIS						int priority = LOW_PRIORITY;						if (easyChange && !isAnonymousInnerClass)							priority = NORMAL_PRIORITY;						boolean b = withinAnonymousClass.matcher(getDottedClassName()).find();						String bug = "SIC_INNER_SHOULD_BE_STATIC";						if (isAnonymousInnerClass)							bug = "SIC_INNER_SHOULD_BE_STATIC_ANON";						else if (!easyChange)							bug = "SIC_INNER_SHOULD_BE_STATIC_NEEDS_THIS";						bugReporter.reportBug(new BugInstance(this, bug, priority)								.addClass(className));					}				}			} else {				if (constantFields.contains(f)) {					if (!f.isStatic())						bugReporter.reportBug(addClassFieldAndAccess(new BugInstance(this,								"SS_SHOULD_BE_STATIC",								NORMAL_PRIORITY), f));				} else if (fieldsOfSerializableOrNativeClassed.contains(f)) {					// ignore it				} else if (!writtenFields.contains(f) && f.isResolved())					bugReporter.reportBug(new BugInstance(this, "UUF_UNUSED_FIELD", NORMAL_PRIORITY)							.addClass(className)							.addField(f).lowerPriorityIfDeprecated());				else if (f.getName().toLowerCase().indexOf("guardian") < 0) {					int priority = NORMAL_PRIORITY;					if (f.isStatic()) priority++;					if (finalFields.contains(f)) priority++;					bugReporter.reportBug(addClassFieldAndAccess(new BugInstance(this, "URF_UNREAD_FIELD", priority),f));				}			}		}	}	/**	 * @param instance	 * @return	 */	private BugInstance addClassFieldAndAccess(BugInstance instance, XField f) {		instance.addClass(f.getClassName()).addField(f);		if (fieldAccess.containsKey(f))			instance.add(fieldAccess.get(f));		return instance;	}}

⌨️ 快捷键说明

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