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

📄 dumbmethods.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
				&& getClassConstantOperand().equals("java/lang/String")				&& getNameConstantOperand().equals("<init>")				&& getSigConstantOperand().equals("()V"))			if (alreadyReported.add(getRefConstantOperand()))				bugReporter.reportBug(new BugInstance(this, "DM_STRING_VOID_CTOR", NORMAL_PRIORITY)						.addClassAndMethod(this)						.addSourceLine(this));		if (!isPublicStaticVoidMain && seen == INVOKESTATIC				&& getClassConstantOperand().equals("java/lang/System")				&& getNameConstantOperand().equals("exit")				&& !getMethodName().equals("processWindowEvent")				&& !getMethodName().startsWith("windowClos")				&& getMethodName().indexOf("exit") == -1				&& getMethodName().indexOf("Exit") == -1				&& getMethodName().indexOf("crash") == -1				&& getMethodName().indexOf("Crash") == -1				&& getMethodName().indexOf("die") == -1				&& getMethodName().indexOf("Die") == -1				&& getMethodName().indexOf("main") == -1)			accumulator.accumulateBug(new BugInstance(this, "DM_EXIT", 				getMethod().isStatic() ? LOW_PRIORITY : NORMAL_PRIORITY)					.addClassAndMethod(this), 						SourceLineAnnotation.fromVisitedInstruction(this));		if (((seen == INVOKESTATIC				&& getClassConstantOperand().equals("java/lang/System"))				|| (seen == INVOKEVIRTUAL				&& getClassConstantOperand().equals("java/lang/Runtime")))				&& getNameConstantOperand().equals("gc")				&& getSigConstantOperand().equals("()V")				&& !getDottedClassName().startsWith("java.lang")				&& !getMethodName().startsWith("gc")				&& !getMethodName().endsWith("gc"))			if (alreadyReported.add(getRefConstantOperand())) {				// System.out.println("Saw call to GC");				if (isPublicStaticVoidMain) {					// System.out.println("Skipping GC complaint in main method");					return;				}				if (isTestMethod(getMethod())) return;				// Just save this report in a field; it will be flushed				// IFF there were no calls to System.currentTimeMillis();				// in the method.				gcInvocationBugReport = new BugInstance(this, "DM_GC", HIGH_PRIORITY)						.addClassAndMethod(this)						.addSourceLine(this);				gcInvocationPC = getPC();				//System.out.println("GC invocation at pc " + PC);			}		if (!isSynthetic && (seen == INVOKESPECIAL)				&& getClassConstantOperand().equals("java/lang/Boolean")				&& getNameConstantOperand().equals("<init>")				&& !getClassName().equals("java/lang/Boolean")				&& alreadyReported.add(getRefConstantOperand())) {			int majorVersion = getThisClass().getMajor();			if (majorVersion >= MAJOR_1_4)				bugReporter.reportBug(new BugInstance(this, "DM_BOOLEAN_CTOR", NORMAL_PRIORITY)				.addClassAndMethod(this)				.addSourceLine(this));		}		if ((seen == INVOKESTATIC)				&& getClassConstantOperand().equals("java/lang/System")				&& (getNameConstantOperand().equals("currentTimeMillis")				   || getNameConstantOperand().equals("nanoTime")))			sawCurrentTimeMillis = true;		if ((seen == INVOKEVIRTUAL)				&& getClassConstantOperand().equals("java/lang/String")				&& getNameConstantOperand().equals("toString")				&& getSigConstantOperand().equals("()Ljava/lang/String;"))			if (alreadyReported.add(getRefConstantOperand()))				bugReporter.reportBug(new BugInstance(this, "DM_STRING_TOSTRING", NORMAL_PRIORITY)						.addClassAndMethod(this)						.addSourceLine(this));		if ((seen == INVOKEVIRTUAL)				&& getClassConstantOperand().equals("java/lang/String")				&& (getNameConstantOperand().equals("toUpperCase")				||  getNameConstantOperand().equals("toLowerCase"))				&& getSigConstantOperand().equals("()Ljava/lang/String;"))			if (alreadyReported.add(getRefConstantOperand()))				bugReporter.reportBug(new BugInstance(this, "DM_CONVERT_CASE", LOW_PRIORITY)						.addClassAndMethod(this)						.addSourceLine(this));		if ((seen == INVOKESPECIAL) && getNameConstantOperand().equals("<init>")) {			String cls = getClassConstantOperand();			String sig = getSigConstantOperand();			if ((cls.equals("java/lang/Integer") && sig.equals("(I)V"))			||  (cls.equals("java/lang/Float") && sig.equals("(F)V"))			||  (cls.equals("java/lang/Double") && sig.equals("(D)V"))			||  (cls.equals("java/lang/Long") && sig.equals("(J)V"))			||  (cls.equals("java/lang/Byte") && sig.equals("(B)V"))			||  (cls.equals("java/lang/Character") && sig.equals("(C)V"))			||  (cls.equals("java/lang/Short") && sig.equals("(S)V"))			||  (cls.equals("java/lang/Boolean") && sig.equals("(Z)V"))) {				primitiveObjCtorSeen = cls;			} else {				primitiveObjCtorSeen = null;			}		} else if ((primitiveObjCtorSeen != null)			   &&  (seen == INVOKEVIRTUAL) 			   &&   getNameConstantOperand().equals("toString")			   &&   getClassConstantOperand().equals(primitiveObjCtorSeen)			   &&   getSigConstantOperand().equals("()Ljava/lang/String;")) {				bugReporter.reportBug(new BugInstance(this, "DM_BOXED_PRIMITIVE_TOSTRING", LOW_PRIORITY)						.addClassAndMethod(this)						.addSourceLine(this));			primitiveObjCtorSeen = null;		}		else			primitiveObjCtorSeen = null;		if ((seen == INVOKESPECIAL) && getNameConstantOperand().equals("<init>")) {			ctorSeen = true;		} else if (ctorSeen 				&& (seen == INVOKEVIRTUAL) 				&& getClassConstantOperand().equals("java/lang/Object")				&& getNameConstantOperand().equals("getClass")				&& getSigConstantOperand().equals("()Ljava/lang/Class;")) {					accumulator.accumulateBug(new BugInstance(this, "DM_NEW_FOR_GETCLASS", LOW_PRIORITY)							.addClassAndMethod(this), this);			ctorSeen = false;		} else {			ctorSeen = false;		}		if (jdk15ChecksEnabled				&& (seen == INVOKEVIRTUAL)				&& isMonitorWait(getNameConstantOperand(), getSigConstantOperand())) {			checkMonitorWait();		}		if ((seen == INVOKESPECIAL) 		&&  getNameConstantOperand().equals("<init>")		&&  getClassConstantOperand().equals("java/lang/Thread")) {			String sig = getSigConstantOperand();			if (sig.equals("()V")			||  sig.equals("(Ljava/lang/String;)V")			||  sig.equals("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"))				if (!getMethodName().equals("<init>") || (getPC() > 20)) {					bugReporter.reportBug(new BugInstance(this, "DM_USELESS_THREAD", LOW_PRIORITY)							.addClassAndMethod(this)							.addSourceLine(this));				}		}	} finally {		stack.sawOpcode(this,seen);		prevOpcode = seen;	}	}	/**	 * Return index of stack entry that must be nonnegative.	 * 	 * Return -1 if no stack entry is required to be nonnegative.	 * @param seen	 * @return	 */	private int stackEntryThatMustBeNonnegative(int seen) {		switch(seen) {		case INVOKEINTERFACE:			if (getClassConstantOperand().equals("java/util/List")) {				return getStackEntryOfListCallThatMustBeNonnegative();			}			break;		case INVOKEVIRTUAL:			if (getClassConstantOperand().equals("java/util/LinkedList") || getClassConstantOperand().equals("java/util/ArrayList")) {				return getStackEntryOfListCallThatMustBeNonnegative();			}			break;		case IALOAD:		case AALOAD:		case SALOAD:		case CALOAD:		case BALOAD:		case LALOAD:		case DALOAD:		case FALOAD:			return 0;		case IASTORE:		case AASTORE:		case SASTORE:		case CASTORE:		case BASTORE:		case LASTORE:		case DASTORE:		case FASTORE:			return 1;		}		return -1;	}	private int getStackEntryOfListCallThatMustBeNonnegative() {		String name = getNameConstantOperand();		if ((name.equals("add") || name.equals("set"))			&& getSigConstantOperand().startsWith("(I"))			return 1;		if ((name.equals("get") || name.equals("remove"))				&& getSigConstantOperand().startsWith("(I)"))				return 0;		return -1;	}	private void checkMonitorWait() {		try {			TypeDataflow typeDataflow = getClassContext().getTypeDataflow(getMethod());			TypeDataflow.LocationAndFactPair pair = typeDataflow.getLocationAndFactForInstruction(getPC());			if (pair == null)				return;			Type receiver = pair.frame.getInstance(					pair.location.getHandle().getInstruction(),					getClassContext().getConstantPoolGen()			);			if (!(receiver instanceof ReferenceType))				return;			if (Hierarchy.isSubtype((ReferenceType) receiver, CONDITION_TYPE)) {				bugReporter.reportBug(new BugInstance(this, "DM_MONITOR_WAIT_ON_CONDITION", HIGH_PRIORITY)						.addClassAndMethod(this)						.addSourceLine(this));			}		} catch (ClassNotFoundException e) {			bugReporter.reportMissingClass(e);		} catch (DataflowAnalysisException e) {			bugReporter.logError("Exception caught by DumbMethods", e);		} catch (CFGBuilderException e) {			bugReporter.logError("Exception caught by DumbMethods", e);		}	}	private boolean isMonitorWait(String name, String sig) {//		System.out.println("Check call " + name + "," + sig);		return name.equals("wait")				&& (sig.equals("()V") || sig.equals("(J)V") || sig.equals("(JI)V"));	}	@Override	public void visit(Code obj) {		super.visit(obj);		flush();	}	/**	 * A heuristic - how long a catch block for OutOfMemoryError might be.	 */	private static final int OOM_CATCH_LEN = 20;	/**	 * Flush out cached state at the end of a method.	 */	private void flush() {		if (gcInvocationBugReport != null && !sawCurrentTimeMillis) {			// Make sure the GC invocation is not in an exception handler			// for OutOfMemoryError.			boolean outOfMemoryHandler = false;			for (CodeException handler : exceptionTable) {				if (gcInvocationPC < handler.getHandlerPC() ||						gcInvocationPC > handler.getHandlerPC() + OOM_CATCH_LEN)					continue;				int catchTypeIndex = handler.getCatchType();				if (catchTypeIndex > 0) {					ConstantPool cp = getThisClass().getConstantPool();					Constant constant = cp.getConstant(catchTypeIndex);					if (constant instanceof ConstantClass) {						String exClassName = (String) ((ConstantClass) constant).getConstantValue(cp);						if (exClassName.equals("java/lang/OutOfMemoryError")) {							outOfMemoryHandler = true;							break;						}					}				}			}			if (!outOfMemoryHandler)				bugReporter.reportBug(gcInvocationBugReport);		}		sawCurrentTimeMillis = false;		gcInvocationBugReport = null;		alreadyReported.clear();		exceptionTable = null;	}}

⌨️ 快捷键说明

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