📄 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 edu.umd.cs.findbugs.*;import edu.umd.cs.findbugs.ba.*;import java.util.*;import org.apache.bcel.Constants;import org.apache.bcel.classfile.*;import org.apache.bcel.generic.*;/** * 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 final class FindOpenStream extends ResourceTrackingDetector<Stream, StreamResourceTracker> implements StatelessDetector { static final boolean DEBUG = SystemProperties.getBoolean("fos.debug"); static final boolean IGNORE_WRAPPED_UNINTERESTING_STREAMS = !SystemProperties.getBoolean("fos.allowWUS"); /* ---------------------------------------------------------------------- * Tracked resource types * ---------------------------------------------------------------------- */ /** * List of base classes of tracked resources. */ static final ObjectType[] streamBaseList = {ObjectTypeFactory.getInstance("java.io.InputStream"), ObjectTypeFactory.getInstance("java.io.OutputStream"), ObjectTypeFactory.getInstance("java.io.Reader"), ObjectTypeFactory.getInstance("java.io.Writer"), ObjectTypeFactory.getInstance("java.sql.Connection"), ObjectTypeFactory.getInstance("java.sql.PreparedStatement"), ObjectTypeFactory.getInstance("java.sql.Statement"), ObjectTypeFactory.getInstance("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.StringBufferInputStream", "java.io.PipedInputStream" ,"java.io.ObjectInputStream" }, "OS_OPEN_STREAM")); streamFactoryCollection.add(new IOStreamFactory("java.io.OutputStream", new String[]{"java.io.ByteArrayOutputStream", "java.io.PipedOutputStream" , "java.io.ObjectOutputStream" }, "OS_OPEN_STREAM")); streamFactoryCollection.add(new IOStreamFactory("java.io.Reader", new String[]{"java.io.StringReader", "java.io.CharArrayReader", "java.io.PipedReader"}, "OS_OPEN_STREAM")); streamFactoryCollection.add(new IOStreamFactory("java.io.Writer", new String[]{"java.io.StringWriter", "java.io.CharArrayWriter", "java.io.PipedWriter"}, "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("javax.sql.DataSource", "getConnection", "()Ljava/sql/Connection;", "ODR_OPEN_DATABASE_RESOURCE")); streamFactoryCollection.add(new MethodReturnValueStreamFactory("javax.sql.DataSource", "getConnection", "(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;)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;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 * ---------------------------------------------------------------------- */ private List<PotentialOpenStream> potentialOpenStreamList; /* ---------------------------------------------------------------------- * Implementation * ---------------------------------------------------------------------- */ public FindOpenStream(BugReporter bugReporter) { super(bugReporter); this.potentialOpenStreamList = new LinkedList<PotentialOpenStream>(); } @Override public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } } // List of words that must appear in names of classes which // create possible resources to be tracked. If we don't see a // class containing one of these words, then we don't run the // detector on the class. private static final String[] PRESCREEN_CLASS_LIST = { "Stream", "Reader", "Writer", "DriverManager", "Connection", "Statement" };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -