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

📄 findopenstream.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	/* (non-Javadoc)	 * @see edu.umd.cs.findbugs.Detector#visitClassContext(edu.umd.cs.findbugs.ba.ClassContext)	 */	@Override		 public void visitClassContext(ClassContext classContext) {		JavaClass jclass = classContext.getJavaClass();		// Check to see if the class references any other classes		// which could be resources we want to track.		// If we don't find any such classes, we skip analyzing		// the class.  (Note: could do this by method.)		boolean sawResourceClass = false;		for (int i = 0; i < jclass.getConstantPool().getLength(); ++i) {			Constant constant = jclass.getConstantPool().getConstant(i);			String className = null;			if (constant instanceof ConstantMethodref) {				ConstantMethodref cmr = (ConstantMethodref) constant;				int classIndex = cmr.getClassIndex();				className = jclass.getConstantPool().getConstantString(						classIndex, Constants.CONSTANT_Class);			} else if (constant instanceof ConstantInterfaceMethodref) {				ConstantInterfaceMethodref cmr = (ConstantInterfaceMethodref) constant;				int classIndex = cmr.getClassIndex();				className = jclass.getConstantPool().getConstantString(						classIndex, Constants.CONSTANT_Class);			}			if (className != null) {				if (DEBUG) System.out.println("FindOpenStream: saw class " + className);				for (String aPRESCREEN_CLASS_LIST : PRESCREEN_CLASS_LIST) {					if (className.indexOf(aPRESCREEN_CLASS_LIST) >= 0) {						sawResourceClass = true;						break;					}				}			}		}		if (sawResourceClass) {			super.visitClassContext(classContext);		}	}	@Override		 public boolean prescreen(ClassContext classContext, Method method) {		BitSet bytecodeSet = classContext.getBytecodeSet(method);		if (bytecodeSet == null) return false;		return bytecodeSet.get(Constants.NEW)				|| bytecodeSet.get(Constants.INVOKEINTERFACE)				|| bytecodeSet.get(Constants.INVOKESPECIAL)				|| bytecodeSet.get(Constants.INVOKESTATIC)				|| bytecodeSet.get(Constants.INVOKEVIRTUAL);	}	@Override		 public StreamResourceTracker getResourceTracker(ClassContext classContext, Method method) {		return new StreamResourceTracker(streamFactoryList, bugReporter);	}	public static boolean isMainMethod(Method method) {		return method.isStatic()				&& method.getName().equals("main")				&& method.getSignature().equals("([Ljava/lang/String;)V");	}	@Override		 public void analyzeMethod(ClassContext classContext, Method method,							  StreamResourceTracker resourceTracker,							  ResourceCollection<Stream> resourceCollection)			throws CFGBuilderException, DataflowAnalysisException {		if (isMainMethod(method)) return;		potentialOpenStreamList.clear();		JavaClass javaClass = classContext.getJavaClass();		MethodGen methodGen = classContext.getMethodGen(method);		if (methodGen == null) return;		CFG cfg = classContext.getCFG(method);		// Add Streams passed into the method as parameters.		// These are uninteresting, and should poison		// any streams which wrap them.		try {			Type[] parameterTypeList = Type.getArgumentTypes(methodGen.getSignature());			Location firstLocation = new Location(cfg.getEntry().getFirstInstruction(), cfg.getEntry());			int local = methodGen.isStatic() ? 0 : 1;			for (Type type : parameterTypeList) {				if (type instanceof ObjectType) {					ObjectType objectType = (ObjectType) type;					for (ObjectType streamBase : streamBaseList) {						if (Hierarchy.isSubtype(objectType, streamBase)) {							// OK, found a parameter that is a resource.							// Create a Stream object to represent it.							// The Stream will be uninteresting, so it will							// inhibit reporting for any stream that wraps it.							Stream paramStream =									new Stream(firstLocation, objectType.getClassName(), streamBase.getClassName());							paramStream.setIsOpenOnCreation(true);							paramStream.setOpenLocation(firstLocation);							paramStream.setInstanceParam(local);							resourceCollection.addPreexistingResource(paramStream);							break;						}					}				}				switch (type.getType()) {				case Constants.T_LONG:				case Constants.T_DOUBLE:					local += 2;					break;				default:					local += 1;					break;				}			}		} catch (ClassNotFoundException e) {			bugReporter.reportMissingClass(e);		}		// Set precomputed map of Locations to Stream creation points.		// That way, the StreamResourceTracker won't have to		// repeatedly try to figure out where Streams are created.		resourceTracker.setResourceCollection(resourceCollection);		super.analyzeMethod(classContext, method, resourceTracker, resourceCollection);		// Compute streams that escape into other streams:		// this takes wrapper streams into account.		// This will also compute equivalence classes of streams,		// so that if one stream in a class is closed,		// they are all considered closed.		// (FIXME: this is too simplistic, especially if buffering		// is involved.  Sometime we should really think harder		// about how this should work.)		resourceTracker.markTransitiveUninterestingStreamEscapes();		// For each stream closed on all paths, mark its equivalence		// class as being closed.		for (Iterator<Stream> i = resourceCollection.resourceIterator(); i.hasNext();) {			Stream stream = i.next();			StreamEquivalenceClass equivalenceClass = resourceTracker.getStreamEquivalenceClass(stream);			if (stream.isClosed())				equivalenceClass.setClosed();		}		// Iterate through potential open streams, reporting warnings		// for the "interesting" streams that haven't been closed		// (and aren't in an equivalence class with another stream		// that was closed).		for (PotentialOpenStream pos : potentialOpenStreamList) {			Stream stream = pos.stream;			if (stream.isClosed())				// Stream was in an equivalence class with another				// stream that was properly closed.				continue;			if (stream.isUninteresting())				continue;			Location openLocation = stream.getOpenLocation();			if (openLocation == null)				continue;			if (IGNORE_WRAPPED_UNINTERESTING_STREAMS					&& resourceTracker.isUninterestingStreamEscape(stream))				continue;			String sourceFile = javaClass.getSourceFileName();			bugReporter.reportBug(new BugInstance(this, pos.bugType, pos.priority)					.addClassAndMethod(methodGen, sourceFile)					.addTypeOfNamedClass(stream.getStreamBase()).describe(TypeAnnotation.CLOSEIT_ROLE)					.addSourceLine(classContext, methodGen, sourceFile, stream.getLocation().getHandle()));		}	}	@Override		 public void inspectResult(ClassContext classContext, MethodGen methodGen, CFG cfg,							  Dataflow<ResourceValueFrame, ResourceValueAnalysis<Stream>> dataflow, Stream stream) {		ResourceValueFrame exitFrame = dataflow.getResultFact(cfg.getExit());		int exitStatus = exitFrame.getStatus();		if (exitStatus == ResourceValueFrame.OPEN				|| exitStatus == ResourceValueFrame.OPEN_ON_EXCEPTION_PATH) {			// FIXME: Stream object should be queried for the			// priority.			String bugType = stream.getBugType();			int priority = NORMAL_PRIORITY;			if (exitStatus == ResourceValueFrame.OPEN_ON_EXCEPTION_PATH) {				bugType += "_EXCEPTION_PATH";				priority = LOW_PRIORITY;			}			potentialOpenStreamList.add(new PotentialOpenStream(bugType, priority, stream));		} else if (exitStatus == ResourceValueFrame.CLOSED) {			// Remember that this stream was closed on all paths.			// Later, we will mark all of the streams in its equivalence class			// as having been closed.			stream.setClosed();		}	}	public static void main(String[] argv) throws Exception {		if (argv.length != 3) {			System.err.println("Usage: " + FindOpenStream.class.getName() +					" <class file> <method name> <bytecode offset>");			System.exit(1);		}		String classFile = argv[0];		String methodName = argv[1];		int offset = Integer.parseInt(argv[2]);		ResourceValueAnalysisTestDriver<Stream, StreamResourceTracker> driver =				new ResourceValueAnalysisTestDriver<Stream, StreamResourceTracker>() {					@Override								 public StreamResourceTracker createResourceTracker(ClassContext classContext, Method method) {						return new StreamResourceTracker(streamFactoryList, classContext.getLookupFailureCallback());					}				};		driver.execute(classFile, methodName, offset);	}}// vim:ts=3

⌨️ 快捷键说明

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