📄 findopenstream.java
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003,2004 University of Maryland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package edu.umd.cs.findbugs.detect;import java.util.*;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.ResourceCollection;import edu.umd.cs.findbugs.ResourceTrackingDetector;import edu.umd.cs.findbugs.ba.*;import org.apache.bcel.Constants;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.Method;import org.apache.bcel.generic.MethodGen;import org.apache.bcel.generic.ObjectType;import org.apache.bcel.generic.Type;/** * A Detector to look for streams that are opened in a method, * do not escape the method, and are not closed on all paths * out of the method. Note that "stream" is a bit misleading, * since we also use the detector to look for database resources * that aren't closed. * * @author David Hovemeyer */public class FindOpenStream extends ResourceTrackingDetector<Stream, StreamResourceTracker> { static final boolean DEBUG = Boolean.getBoolean("fos.debug"); static final boolean IGNORE_WRAPPED_UNINTERESTING_STREAMS = !Boolean.getBoolean("fos.allowWUS"); /* ---------------------------------------------------------------------- * Tracked resource types * ---------------------------------------------------------------------- */ /** * List of base classes of tracked resources. */ static final ObjectType[] streamBaseList = {new ObjectType("java.io.InputStream"), new ObjectType("java.io.OutputStream"), new ObjectType("java.io.Reader"), new ObjectType("java.io.Writer"), new ObjectType("java.sql.Connection"), new ObjectType("java.sql.Statement"), new ObjectType("java.sql.ResultSet")}; /** * StreamFactory objects used to detect resources * created within analyzed methods. */ static final StreamFactory[] streamFactoryList; static { ArrayList<StreamFactory> streamFactoryCollection = new ArrayList<StreamFactory>(); // Examine InputStreams, OutputStreams, Readers, and Writers, // ignoring byte array, object stream, char array, and String variants. streamFactoryCollection.add(new IOStreamFactory("java.io.InputStream", new String[]{"java.io.ByteArrayInputStream", "java.io.ObjectInputStream"}, "OS_OPEN_STREAM")); streamFactoryCollection.add(new IOStreamFactory("java.io.OutputStream", new String[]{"java.io.ByteArrayOutputStream", "java.io.ObjectOutputStream"}, "OS_OPEN_STREAM")); streamFactoryCollection.add(new IOStreamFactory("java.io.Reader", new String[]{"java.io.StringReader", "java.io.CharArrayReader"}, "OS_OPEN_STREAM")); streamFactoryCollection.add(new IOStreamFactory("java.io.Writer", new String[]{"java.io.StringWriter", "java.io.CharArrayWriter"}, "OS_OPEN_STREAM")); // Ignore socket input and output streams streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.net.Socket", "getInputStream", "()Ljava/io/InputStream;")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.net.Socket", "getOutputStream", "()Ljava/io/OutputStream;")); // Ignore System.{in,out,err} streamFactoryCollection.add(new StaticFieldLoadStreamFactory("java.io.InputStream", "java.lang.System", "in", "Ljava/io/InputStream;")); streamFactoryCollection.add(new StaticFieldLoadStreamFactory("java.io.OutputStream", "java.lang.System", "out", "Ljava/io/PrintStream;")); streamFactoryCollection.add(new StaticFieldLoadStreamFactory("java.io.OutputStream", "java.lang.System", "err", "Ljava/io/PrintStream;")); // Ignore input streams loaded from instance fields streamFactoryCollection.add(new InstanceFieldLoadStreamFactory("java.io.InputStream")); streamFactoryCollection.add(new InstanceFieldLoadStreamFactory("java.io.Reader")); // Ignore output streams loaded from instance fields. // FIXME: what we really should do here is ignore the stream // loaded from the field, but report any streams that wrap // it. This is an important and useful distinction that the // detector currently doesn't handle. Should be fairly // easy to add. streamFactoryCollection.add(new InstanceFieldLoadStreamFactory("java.io.OutputStream")); streamFactoryCollection.add(new InstanceFieldLoadStreamFactory("java.io.Writer")); // JDBC objects streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareStatement", "(Ljava/lang/String;)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareStatement", "(Ljava/lang/String;I)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareStatement", "(Ljava/lang/String;[I)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareStatement", "(Ljava/lang/String;II)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareStatement", "(Ljava/lang/String;III)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareStatement", "(Ljava/lang/String;[Ljava/lang/String;)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareCall", "(Ljava/lang/String;)Ljava/sql/CallableStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareCall", "(Ljava/lang/String;II)Ljava/sql/CallableStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "prepareCall", "(Ljava/lang/String;III)Ljava/sql/CallableStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.DriverManager", "getConnection", "(Ljava/lang/String;)Ljava/sql/Connection;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.DriverManager", "getConnection", "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.DriverManager", "getConnection", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/sql/Connection;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "createStatement", "()Ljava/sql/Statement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "createStatement", "(II)Ljava/sql/Statement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "createStatement", "(III)Ljava/sql/Statement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "createStatement", "(Ljava/lang/String;I)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "createStatement", "(Ljava/lang/String;II)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "createStatement", "(Ljava/lang/String;III)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "createStatement", "(Ljava/lang/String;[I)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("java.sql.Connection", "createStatement", "(Ljava/lang/String;[Ljava/lang/String;)Ljava/sql/PreparedStatement;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryList = streamFactoryCollection.toArray(new StreamFactory[streamFactoryCollection.size()]); } /* ---------------------------------------------------------------------- * Helper classes * ---------------------------------------------------------------------- */ private static class PotentialOpenStream { public final String bugType; public final int priority; public final Stream stream; public PotentialOpenStream(String bugType, int priority, Stream stream) { this.bugType = bugType; this.priority = priority; this.stream = stream; } } /* ---------------------------------------------------------------------- * Fields
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -