From 7b15b88072a6ee394043b50d87006f86f7270d80 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Wed, 28 Dec 2022 09:32:18 -0800 Subject: [PATCH 1/5] WIP --- checker/build.gradle | 2 ++ .../checker/mustcall/IOUtils.astub | 34 +++++++++++++++++++ .../checker/mustcall/MustCallChecker.java | 1 + checker/tests/resourceleak/IOUtilsTest.java | 7 ++++ 4 files changed, 44 insertions(+) create mode 100644 checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub create mode 100644 checker/tests/resourceleak/IOUtilsTest.java diff --git a/checker/build.gradle b/checker/build.gradle index d09b9f95256..41bd0eda90a 100644 --- a/checker/build.gradle +++ b/checker/build.gradle @@ -64,6 +64,8 @@ dependencies { testImplementation platform('com.amazonaws:aws-java-sdk-bom:1.12.293') // For the Resource Leak Checker's support for JavaEE. testImplementation 'javax.servlet:javax.servlet-api:3.1.0' + // For the Resource Leak Checker's support for IOUtils. + testImplementation 'commons-io:commons-io:2.11.0' testImplementation group: 'junit', name: 'junit', version: '4.13.2' testImplementation project(':framework-test') diff --git a/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub b/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub new file mode 100644 index 00000000000..1037d9e8c98 --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub @@ -0,0 +1,34 @@ +package org.apache.commons.io; + +import org.checkerframework.checker.mustcall.qual.*; +import org.checkerframework.checker.calledmethods.qual.*; + +class IOUtils { + @EnsuresCalledMethods(value = "#1", methods = "close") + static void closeQuietly(Reader arg0); + @EnsuresCalledMethods(value = "#1", methods = "close") + static void closeQuietly(Writer arg0); + @EnsuresCalledMethods(value = "#1", methods = "close") + static void closeQuietly(InputStream arg0); + @EnsuresCalledMethods(value = "#1", methods = "close") + static void closeQuietly(OutputStream arg0); + @EnsuresCalledMethods(value = "#1", methods = "close") + static void closeQuietly(Closeable arg0); + @SuppressWarnings("ensuresvarargs.unverified") + @EnsuresCalledMethodsVarArgs("close") + static void closeQuietly(Closeable... arg0); + @EnsuresCalledMethods(value = "#1", methods = "close") + static void closeQuietly(Socket arg0); + @EnsuresCalledMethods(value = "#1", methods = "close") + static void closeQuietly(Selector arg0); + @EnsuresCalledMethods(value = "#1", methods = "close") + static void closeQuietly(ServerSocket arg0); + @NotOwning static InputStream toBufferedInputStream(InputStream arg0) throws IOException; + @NotOwning static BufferedReader toBufferedReader(Reader arg0); + @NotOwning static InputStream toInputStream(CharSequence arg0); + @NotOwning static InputStream toInputStream(CharSequence arg0, Charset arg1); + @NotOwning static InputStream toInputStream(CharSequence arg0, String arg1) throws IOException; + @NotOwning static InputStream toInputStream(String arg0); + @NotOwning static InputStream toInputStream(String arg0, Charset arg1); + @NotOwning static InputStream toInputStream(String arg0, String arg1) throws IOException; +} diff --git a/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java b/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java index fc89dfa5733..617fe571db6 100644 --- a/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java @@ -10,6 +10,7 @@ * another. The Resource Leak Checker verifies that the given methods are actually called. */ @StubFiles({ + "IOUtils.astub", "JavaEE.astub", "JdkCompiler.astub", "Reflection.astub", diff --git a/checker/tests/resourceleak/IOUtilsTest.java b/checker/tests/resourceleak/IOUtilsTest.java new file mode 100644 index 00000000000..efdefdbdf23 --- /dev/null +++ b/checker/tests/resourceleak/IOUtilsTest.java @@ -0,0 +1,7 @@ +import org.checkerframework.checker.mustcall.qual.*; + +class IOUtilsTest { + static void foo(@Owning java.io.InputStream inputStream) { + org.apache.commons.io.IOUtils.closeQuietly(inputStream); + } +} From b41ff3342c78515d0b44a690870621ec13bc8bda Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Wed, 28 Dec 2022 09:50:56 -0800 Subject: [PATCH 2/5] use exact same stub file as before with modified import --- .../checker/mustcall/IOUtils.astub | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub b/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub index 1037d9e8c98..7183a8db57c 100644 --- a/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub +++ b/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub @@ -1,9 +1,18 @@ package org.apache.commons.io; import org.checkerframework.checker.mustcall.qual.*; +import org.checkerframework.common.returnsreceiver.qual.*; import org.checkerframework.checker.calledmethods.qual.*; class IOUtils { + static final char DIR_SEPARATOR_UNIX; + static final char DIR_SEPARATOR_WINDOWS; + static final char DIR_SEPARATOR; + static final String LINE_SEPARATOR_UNIX; + static final String LINE_SEPARATOR_WINDOWS; + static final String LINE_SEPARATOR; + IOUtils(); + static void close(URLConnection arg0); @EnsuresCalledMethods(value = "#1", methods = "close") static void closeQuietly(Reader arg0); @EnsuresCalledMethods(value = "#1", methods = "close") @@ -25,10 +34,102 @@ class IOUtils { static void closeQuietly(ServerSocket arg0); @NotOwning static InputStream toBufferedInputStream(InputStream arg0) throws IOException; @NotOwning static BufferedReader toBufferedReader(Reader arg0); + static byte[] toByteArray(InputStream arg0) throws IOException; + static byte[] toByteArray(InputStream arg0, long arg1) throws IOException; + static byte[] toByteArray(InputStream arg0, int arg1) throws IOException; + static byte[] toByteArray(Reader arg0) throws IOException; + static byte[] toByteArray(Reader arg0, Charset arg1) throws IOException; + static byte[] toByteArray(Reader arg0, String arg1) throws IOException; + @java.lang.Deprecated +static byte[] toByteArray(String arg0) throws IOException; + static byte[] toByteArray(URI arg0) throws IOException; + static byte[] toByteArray(URL arg0) throws IOException; + static byte[] toByteArray(URLConnection arg0) throws IOException; + static char[] toCharArray(InputStream arg0) throws IOException; + static char[] toCharArray(InputStream arg0, Charset arg1) throws IOException; + static char[] toCharArray(InputStream arg0, String arg1) throws IOException; + static char[] toCharArray(Reader arg0) throws IOException; + static String toString(InputStream arg0) throws IOException; + static String toString(InputStream arg0, Charset arg1) throws IOException; + static String toString(InputStream arg0, String arg1) throws IOException; + static String toString(Reader arg0) throws IOException; + static String toString(URI arg0) throws IOException; + static String toString(URI arg0, Charset arg1) throws IOException; + static String toString(URI arg0, String arg1) throws IOException; + static String toString(URL arg0) throws IOException; + static String toString(URL arg0, Charset arg1) throws IOException; + static String toString(URL arg0, String arg1) throws IOException; + @java.lang.Deprecated +static String toString(byte[] arg0) throws IOException; + static String toString(byte[] arg0, String arg1) throws IOException; + static List readLines(InputStream arg0) throws IOException; + static List readLines(InputStream arg0, Charset arg1) throws IOException; + static List readLines(InputStream arg0, String arg1) throws IOException; + static List readLines(Reader arg0) throws IOException; + static LineIterator lineIterator(Reader arg0); + static LineIterator lineIterator(InputStream arg0, Charset arg1) throws IOException; + static LineIterator lineIterator(InputStream arg0, String arg1) throws IOException; @NotOwning static InputStream toInputStream(CharSequence arg0); @NotOwning static InputStream toInputStream(CharSequence arg0, Charset arg1); @NotOwning static InputStream toInputStream(CharSequence arg0, String arg1) throws IOException; @NotOwning static InputStream toInputStream(String arg0); @NotOwning static InputStream toInputStream(String arg0, Charset arg1); @NotOwning static InputStream toInputStream(String arg0, String arg1) throws IOException; + static void write(byte[] arg0, OutputStream arg1) throws IOException; + static void write(byte[] arg0, Writer arg1) throws IOException; + static void write(byte[] arg0, Writer arg1, Charset arg2) throws IOException; + static void write(byte[] arg0, Writer arg1, String arg2) throws IOException; + static void write(char[] arg0, Writer arg1) throws IOException; + static void write(char[] arg0, OutputStream arg1) throws IOException; + static void write(char[] arg0, OutputStream arg1, Charset arg2) throws IOException; + static void write(char[] arg0, OutputStream arg1, String arg2) throws IOException; + static void write(CharSequence arg0, Writer arg1) throws IOException; + static void write(CharSequence arg0, OutputStream arg1) throws IOException; + static void write(CharSequence arg0, OutputStream arg1, Charset arg2) throws IOException; + static void write(CharSequence arg0, OutputStream arg1, String arg2) throws IOException; + static void write(String arg0, Writer arg1) throws IOException; + static void write(String arg0, OutputStream arg1) throws IOException; + static void write(String arg0, OutputStream arg1, Charset arg2) throws IOException; + static void write(String arg0, OutputStream arg1, String arg2) throws IOException; + @java.lang.Deprecated +static void write(StringBuffer arg0, Writer arg1) throws IOException; + @java.lang.Deprecated +static void write(StringBuffer arg0, OutputStream arg1) throws IOException; + @java.lang.Deprecated +static void write(StringBuffer arg0, OutputStream arg1, String arg2) throws IOException; + static void writeLines(Collection arg0, String arg1, OutputStream arg2) throws IOException; + static void writeLines(Collection arg0, String arg1, OutputStream arg2, Charset arg3) throws IOException; + static void writeLines(Collection arg0, String arg1, OutputStream arg2, String arg3) throws IOException; + static void writeLines(Collection arg0, String arg1, Writer arg2) throws IOException; + static int copy(InputStream arg0, OutputStream arg1) throws IOException; + static long copyLarge(InputStream arg0, OutputStream arg1) throws IOException; + static long copyLarge(InputStream arg0, OutputStream arg1, byte[] arg2) throws IOException; + static long copyLarge(InputStream arg0, OutputStream arg1, long arg2, long arg3) throws IOException; + static long copyLarge(InputStream arg0, OutputStream arg1, long arg2, long arg3, byte[] arg4) throws IOException; + static void copy(InputStream arg0, Writer arg1) throws IOException; + static void copy(InputStream arg0, Writer arg1, Charset arg2) throws IOException; + static void copy(InputStream arg0, Writer arg1, String arg2) throws IOException; + static int copy(Reader arg0, Writer arg1) throws IOException; + static long copyLarge(Reader arg0, Writer arg1) throws IOException; + static long copyLarge(Reader arg0, Writer arg1, char[] arg2) throws IOException; + static long copyLarge(Reader arg0, Writer arg1, long arg2, long arg3) throws IOException; + static long copyLarge(Reader arg0, Writer arg1, long arg2, long arg3, char[] arg4) throws IOException; + static void copy(Reader arg0, OutputStream arg1) throws IOException; + static void copy(Reader arg0, OutputStream arg1, Charset arg2) throws IOException; + static void copy(Reader arg0, OutputStream arg1, String arg2) throws IOException; + static boolean contentEquals(InputStream arg0, InputStream arg1) throws IOException; + static boolean contentEquals(Reader arg0, Reader arg1) throws IOException; + static boolean contentEqualsIgnoreEOL(Reader arg0, Reader arg1) throws IOException; + static long skip(InputStream arg0, long arg1) throws IOException; + static long skip(Reader arg0, long arg1) throws IOException; + static void skipFully(InputStream arg0, long arg1) throws IOException; + static void skipFully(Reader arg0, long arg1) throws IOException; + static int read(Reader arg0, char[] arg1, int arg2, int arg3) throws IOException; + static int read(Reader arg0, char[] arg1) throws IOException; + static int read(InputStream arg0, byte[] arg1, int arg2, int arg3) throws IOException; + static int read(InputStream arg0, byte[] arg1) throws IOException; + static void readFully(Reader arg0, char[] arg1, int arg2, int arg3) throws IOException; + static void readFully(Reader arg0, char[] arg1) throws IOException; + static void readFully(InputStream arg0, byte[] arg1, int arg2, int arg3) throws IOException; + static void readFully(InputStream arg0, byte[] arg1) throws IOException; } From 804b3c7499fa251e3cfa912e1a0099380fe87412 Mon Sep 17 00:00:00 2001 From: Suzanne Millstein Date: Tue, 3 Jan 2023 10:09:17 -0800 Subject: [PATCH 3/5] Move IOUtils.astub to the correct place. --- .../org/checkerframework/checker/mustcall/MustCallChecker.java | 1 - .../checker/{mustcall => resourceleak}/IOUtils.astub | 0 .../checker/resourceleak/ResourceLeakChecker.java | 2 ++ 3 files changed, 2 insertions(+), 1 deletion(-) rename checker/src/main/java/org/checkerframework/checker/{mustcall => resourceleak}/IOUtils.astub (100%) diff --git a/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java b/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java index 617fe571db6..fc89dfa5733 100644 --- a/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java @@ -10,7 +10,6 @@ * another. The Resource Leak Checker verifies that the given methods are actually called. */ @StubFiles({ - "IOUtils.astub", "JavaEE.astub", "JdkCompiler.astub", "Reflection.astub", diff --git a/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub b/checker/src/main/java/org/checkerframework/checker/resourceleak/IOUtils.astub similarity index 100% rename from checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub rename to checker/src/main/java/org/checkerframework/checker/resourceleak/IOUtils.astub diff --git a/checker/src/main/java/org/checkerframework/checker/resourceleak/ResourceLeakChecker.java b/checker/src/main/java/org/checkerframework/checker/resourceleak/ResourceLeakChecker.java index 5f5401a6b49..cfda961fb0a 100644 --- a/checker/src/main/java/org/checkerframework/checker/resourceleak/ResourceLeakChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/resourceleak/ResourceLeakChecker.java @@ -8,6 +8,7 @@ import org.checkerframework.checker.mustcall.MustCallNoCreatesMustCallForChecker; import org.checkerframework.common.basetype.BaseTypeChecker; import org.checkerframework.common.basetype.BaseTypeVisitor; +import org.checkerframework.framework.qual.StubFiles; import org.checkerframework.framework.source.SupportedOptions; /** @@ -23,6 +24,7 @@ MustCallChecker.NO_LIGHTWEIGHT_OWNERSHIP, MustCallChecker.NO_RESOURCE_ALIASES }) +@StubFiles("IOUtils.astub") public class ResourceLeakChecker extends CalledMethodsChecker { /** From 394d927b6914c6edbba1da183563df0a8478bd64 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Tue, 3 Jan 2023 11:59:13 -0800 Subject: [PATCH 4/5] stub fixes --- .../checker/mustcall/IOUtils.astub | 14 +++ .../checker/mustcall/MustCallChecker.java | 1 + .../checker/resourceleak/IOUtils.astub | 110 ------------------ checker/tests/resourceleak/IOUtilsTest.java | 11 +- 4 files changed, 25 insertions(+), 111 deletions(-) create mode 100644 checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub diff --git a/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub b/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub new file mode 100644 index 00000000000..8f35d8febbd --- /dev/null +++ b/checker/src/main/java/org/checkerframework/checker/mustcall/IOUtils.astub @@ -0,0 +1,14 @@ +package org.apache.commons.io; + +import org.checkerframework.checker.mustcall.qual.*; + +class IOUtils { + @NotOwning static InputStream toBufferedInputStream(InputStream arg0) throws IOException; + @NotOwning static BufferedReader toBufferedReader(Reader arg0); + @NotOwning static InputStream toInputStream(CharSequence arg0); + @NotOwning static InputStream toInputStream(CharSequence arg0, Charset arg1); + @NotOwning static InputStream toInputStream(CharSequence arg0, String arg1) throws IOException; + @NotOwning static InputStream toInputStream(String arg0); + @NotOwning static InputStream toInputStream(String arg0, Charset arg1); + @NotOwning static InputStream toInputStream(String arg0, String arg1) throws IOException; +} diff --git a/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java b/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java index fc89dfa5733..617fe571db6 100644 --- a/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/mustcall/MustCallChecker.java @@ -10,6 +10,7 @@ * another. The Resource Leak Checker verifies that the given methods are actually called. */ @StubFiles({ + "IOUtils.astub", "JavaEE.astub", "JdkCompiler.astub", "Reflection.astub", diff --git a/checker/src/main/java/org/checkerframework/checker/resourceleak/IOUtils.astub b/checker/src/main/java/org/checkerframework/checker/resourceleak/IOUtils.astub index 7183a8db57c..9caed0051ee 100644 --- a/checker/src/main/java/org/checkerframework/checker/resourceleak/IOUtils.astub +++ b/checker/src/main/java/org/checkerframework/checker/resourceleak/IOUtils.astub @@ -1,18 +1,8 @@ package org.apache.commons.io; -import org.checkerframework.checker.mustcall.qual.*; -import org.checkerframework.common.returnsreceiver.qual.*; import org.checkerframework.checker.calledmethods.qual.*; class IOUtils { - static final char DIR_SEPARATOR_UNIX; - static final char DIR_SEPARATOR_WINDOWS; - static final char DIR_SEPARATOR; - static final String LINE_SEPARATOR_UNIX; - static final String LINE_SEPARATOR_WINDOWS; - static final String LINE_SEPARATOR; - IOUtils(); - static void close(URLConnection arg0); @EnsuresCalledMethods(value = "#1", methods = "close") static void closeQuietly(Reader arg0); @EnsuresCalledMethods(value = "#1", methods = "close") @@ -32,104 +22,4 @@ class IOUtils { static void closeQuietly(Selector arg0); @EnsuresCalledMethods(value = "#1", methods = "close") static void closeQuietly(ServerSocket arg0); - @NotOwning static InputStream toBufferedInputStream(InputStream arg0) throws IOException; - @NotOwning static BufferedReader toBufferedReader(Reader arg0); - static byte[] toByteArray(InputStream arg0) throws IOException; - static byte[] toByteArray(InputStream arg0, long arg1) throws IOException; - static byte[] toByteArray(InputStream arg0, int arg1) throws IOException; - static byte[] toByteArray(Reader arg0) throws IOException; - static byte[] toByteArray(Reader arg0, Charset arg1) throws IOException; - static byte[] toByteArray(Reader arg0, String arg1) throws IOException; - @java.lang.Deprecated -static byte[] toByteArray(String arg0) throws IOException; - static byte[] toByteArray(URI arg0) throws IOException; - static byte[] toByteArray(URL arg0) throws IOException; - static byte[] toByteArray(URLConnection arg0) throws IOException; - static char[] toCharArray(InputStream arg0) throws IOException; - static char[] toCharArray(InputStream arg0, Charset arg1) throws IOException; - static char[] toCharArray(InputStream arg0, String arg1) throws IOException; - static char[] toCharArray(Reader arg0) throws IOException; - static String toString(InputStream arg0) throws IOException; - static String toString(InputStream arg0, Charset arg1) throws IOException; - static String toString(InputStream arg0, String arg1) throws IOException; - static String toString(Reader arg0) throws IOException; - static String toString(URI arg0) throws IOException; - static String toString(URI arg0, Charset arg1) throws IOException; - static String toString(URI arg0, String arg1) throws IOException; - static String toString(URL arg0) throws IOException; - static String toString(URL arg0, Charset arg1) throws IOException; - static String toString(URL arg0, String arg1) throws IOException; - @java.lang.Deprecated -static String toString(byte[] arg0) throws IOException; - static String toString(byte[] arg0, String arg1) throws IOException; - static List readLines(InputStream arg0) throws IOException; - static List readLines(InputStream arg0, Charset arg1) throws IOException; - static List readLines(InputStream arg0, String arg1) throws IOException; - static List readLines(Reader arg0) throws IOException; - static LineIterator lineIterator(Reader arg0); - static LineIterator lineIterator(InputStream arg0, Charset arg1) throws IOException; - static LineIterator lineIterator(InputStream arg0, String arg1) throws IOException; - @NotOwning static InputStream toInputStream(CharSequence arg0); - @NotOwning static InputStream toInputStream(CharSequence arg0, Charset arg1); - @NotOwning static InputStream toInputStream(CharSequence arg0, String arg1) throws IOException; - @NotOwning static InputStream toInputStream(String arg0); - @NotOwning static InputStream toInputStream(String arg0, Charset arg1); - @NotOwning static InputStream toInputStream(String arg0, String arg1) throws IOException; - static void write(byte[] arg0, OutputStream arg1) throws IOException; - static void write(byte[] arg0, Writer arg1) throws IOException; - static void write(byte[] arg0, Writer arg1, Charset arg2) throws IOException; - static void write(byte[] arg0, Writer arg1, String arg2) throws IOException; - static void write(char[] arg0, Writer arg1) throws IOException; - static void write(char[] arg0, OutputStream arg1) throws IOException; - static void write(char[] arg0, OutputStream arg1, Charset arg2) throws IOException; - static void write(char[] arg0, OutputStream arg1, String arg2) throws IOException; - static void write(CharSequence arg0, Writer arg1) throws IOException; - static void write(CharSequence arg0, OutputStream arg1) throws IOException; - static void write(CharSequence arg0, OutputStream arg1, Charset arg2) throws IOException; - static void write(CharSequence arg0, OutputStream arg1, String arg2) throws IOException; - static void write(String arg0, Writer arg1) throws IOException; - static void write(String arg0, OutputStream arg1) throws IOException; - static void write(String arg0, OutputStream arg1, Charset arg2) throws IOException; - static void write(String arg0, OutputStream arg1, String arg2) throws IOException; - @java.lang.Deprecated -static void write(StringBuffer arg0, Writer arg1) throws IOException; - @java.lang.Deprecated -static void write(StringBuffer arg0, OutputStream arg1) throws IOException; - @java.lang.Deprecated -static void write(StringBuffer arg0, OutputStream arg1, String arg2) throws IOException; - static void writeLines(Collection arg0, String arg1, OutputStream arg2) throws IOException; - static void writeLines(Collection arg0, String arg1, OutputStream arg2, Charset arg3) throws IOException; - static void writeLines(Collection arg0, String arg1, OutputStream arg2, String arg3) throws IOException; - static void writeLines(Collection arg0, String arg1, Writer arg2) throws IOException; - static int copy(InputStream arg0, OutputStream arg1) throws IOException; - static long copyLarge(InputStream arg0, OutputStream arg1) throws IOException; - static long copyLarge(InputStream arg0, OutputStream arg1, byte[] arg2) throws IOException; - static long copyLarge(InputStream arg0, OutputStream arg1, long arg2, long arg3) throws IOException; - static long copyLarge(InputStream arg0, OutputStream arg1, long arg2, long arg3, byte[] arg4) throws IOException; - static void copy(InputStream arg0, Writer arg1) throws IOException; - static void copy(InputStream arg0, Writer arg1, Charset arg2) throws IOException; - static void copy(InputStream arg0, Writer arg1, String arg2) throws IOException; - static int copy(Reader arg0, Writer arg1) throws IOException; - static long copyLarge(Reader arg0, Writer arg1) throws IOException; - static long copyLarge(Reader arg0, Writer arg1, char[] arg2) throws IOException; - static long copyLarge(Reader arg0, Writer arg1, long arg2, long arg3) throws IOException; - static long copyLarge(Reader arg0, Writer arg1, long arg2, long arg3, char[] arg4) throws IOException; - static void copy(Reader arg0, OutputStream arg1) throws IOException; - static void copy(Reader arg0, OutputStream arg1, Charset arg2) throws IOException; - static void copy(Reader arg0, OutputStream arg1, String arg2) throws IOException; - static boolean contentEquals(InputStream arg0, InputStream arg1) throws IOException; - static boolean contentEquals(Reader arg0, Reader arg1) throws IOException; - static boolean contentEqualsIgnoreEOL(Reader arg0, Reader arg1) throws IOException; - static long skip(InputStream arg0, long arg1) throws IOException; - static long skip(Reader arg0, long arg1) throws IOException; - static void skipFully(InputStream arg0, long arg1) throws IOException; - static void skipFully(Reader arg0, long arg1) throws IOException; - static int read(Reader arg0, char[] arg1, int arg2, int arg3) throws IOException; - static int read(Reader arg0, char[] arg1) throws IOException; - static int read(InputStream arg0, byte[] arg1, int arg2, int arg3) throws IOException; - static int read(InputStream arg0, byte[] arg1) throws IOException; - static void readFully(Reader arg0, char[] arg1, int arg2, int arg3) throws IOException; - static void readFully(Reader arg0, char[] arg1) throws IOException; - static void readFully(InputStream arg0, byte[] arg1, int arg2, int arg3) throws IOException; - static void readFully(InputStream arg0, byte[] arg1) throws IOException; } diff --git a/checker/tests/resourceleak/IOUtilsTest.java b/checker/tests/resourceleak/IOUtilsTest.java index efdefdbdf23..757320760c8 100644 --- a/checker/tests/resourceleak/IOUtilsTest.java +++ b/checker/tests/resourceleak/IOUtilsTest.java @@ -1,7 +1,16 @@ import org.checkerframework.checker.mustcall.qual.*; +import java.io.*; class IOUtilsTest { - static void foo(@Owning java.io.InputStream inputStream) { + static void test1(@Owning InputStream inputStream) { org.apache.commons.io.IOUtils.closeQuietly(inputStream); } + + static void test2(@Owning InputStream inputStream) throws IOException { + try { + InputStream other = org.apache.commons.io.IOUtils.toBufferedInputStream(inputStream); + } finally { + inputStream.close(); + } + } } From dbbb18d9062f10c3fab7e88f7fc57e5f0da49770 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Wed, 4 Jan 2023 06:35:13 -0800 Subject: [PATCH 5/5] Add constructor --- .../checker/resourceleak/ResourceLeakChecker.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/checker/src/main/java/org/checkerframework/checker/resourceleak/ResourceLeakChecker.java b/checker/src/main/java/org/checkerframework/checker/resourceleak/ResourceLeakChecker.java index cfda961fb0a..b5a30070da5 100644 --- a/checker/src/main/java/org/checkerframework/checker/resourceleak/ResourceLeakChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/resourceleak/ResourceLeakChecker.java @@ -27,6 +27,9 @@ @StubFiles("IOUtils.astub") public class ResourceLeakChecker extends CalledMethodsChecker { + /** Creates a ResourceLeakChecker. */ + public ResourceLeakChecker() {} + /** * Command-line option for counting how many must-call obligations were checked by the Resource * Leak Checker, and emitting the number after processing all files. Used for generating tables