You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
3.7 KiB
177 lines
3.7 KiB
/*
|
|
* Copyright (c) 2015 - present Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
package codetoanalyze.java.infer;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.Closeable;
|
|
import java.io.IOException;
|
|
import java.io.StringReader;
|
|
|
|
|
|
class LocalException extends IOException {
|
|
}
|
|
|
|
class SomeResource implements Closeable {
|
|
|
|
void doSomething() throws LocalException {
|
|
if (!CloseableAsResourceExample.star()) {
|
|
throw new LocalException();
|
|
}
|
|
}
|
|
|
|
public void close() {}
|
|
|
|
native void foo(int i);
|
|
native static void bar(SomeResource r);
|
|
|
|
}
|
|
|
|
class Resource implements Closeable {
|
|
public Resource() {
|
|
}
|
|
public void close() {}
|
|
}
|
|
|
|
class Wrapper implements Closeable {
|
|
Resource mR;
|
|
public Wrapper(Resource r) {
|
|
mR = r;
|
|
}
|
|
public void close() {
|
|
mR.close();
|
|
}
|
|
}
|
|
|
|
class Sub extends Wrapper {
|
|
public Sub(Resource r) {
|
|
super(r);
|
|
}
|
|
}
|
|
|
|
class ResourceWithException implements Closeable {
|
|
|
|
public void close() throws IOException {
|
|
if (CloseableAsResourceExample.star()) {
|
|
throw new IOException();
|
|
}
|
|
}
|
|
}
|
|
|
|
public class CloseableAsResourceExample {
|
|
|
|
native static boolean star();
|
|
|
|
void closingCloseable() {
|
|
SomeResource res = new SomeResource();
|
|
res.close();
|
|
}
|
|
|
|
void notClosingCloseable() {
|
|
SomeResource res = new SomeResource();
|
|
} // should report a resource leak
|
|
|
|
void tryWithResource() {
|
|
try (SomeResource res = new SomeResource()) {
|
|
try {
|
|
res.doSomething();
|
|
} catch (LocalException e) {
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
|
|
void withException() throws LocalException {
|
|
SomeResource res = new SomeResource();
|
|
res.doSomething();
|
|
res.close();
|
|
} // should report a resource leak
|
|
|
|
|
|
void closingWrapper() {
|
|
Resource r = new Resource();
|
|
Sub s = new Sub(r);
|
|
s.close();
|
|
}
|
|
|
|
void notClosingWrapper() {
|
|
Sub s = new Sub(new Resource());
|
|
s.mR.close();
|
|
} // should report a resource leak
|
|
|
|
void noNeedToCloseStringReader() {
|
|
StringReader stringReader = new StringReader("paf!");
|
|
}
|
|
|
|
void noNeedToCloseByteArrayOutputStream() {
|
|
ByteArrayOutputStream stream = new ByteArrayOutputStream(42);
|
|
}
|
|
|
|
void noNeedToCloseByteArrayInputStream(byte[] array) {
|
|
ByteArrayInputStream stream = new ByteArrayInputStream(array);
|
|
}
|
|
|
|
void closingWithCloseQuietly() {
|
|
SomeResource r = null;
|
|
try {
|
|
r = new SomeResource();
|
|
r.doSomething();
|
|
} catch (IOException e) {
|
|
} finally {
|
|
Utils.closeQuietly(r);
|
|
}
|
|
}
|
|
|
|
void failToCloseWithCloseQuietly() {
|
|
try {
|
|
SomeResource r = new SomeResource();
|
|
r.doSomething();
|
|
Utils.closeQuietly(r);
|
|
} catch (IOException e) {
|
|
}
|
|
}
|
|
|
|
void noLeakwithExceptionOnClose() throws IOException {
|
|
ResourceWithException res = new ResourceWithException();
|
|
res.close();
|
|
}
|
|
|
|
void noLeakWithCloseQuietlyAndExceptionOnClose() {
|
|
ResourceWithException res = new ResourceWithException();
|
|
Utils.closeQuietly(res);
|
|
}
|
|
|
|
static T sourceOfNullWithResourceLeak() {
|
|
SomeResource r = new SomeResource();
|
|
return null;
|
|
}
|
|
|
|
interface MyCloseable extends Closeable {}
|
|
|
|
class MyResource implements MyCloseable {
|
|
public void close() {}
|
|
}
|
|
|
|
void leakFoundWhenIndirectlyImplementingCloseable() {
|
|
MyResource res = new MyResource();
|
|
}
|
|
|
|
void skippedCallClosesResourceOnArgs() {
|
|
SomeResource res = new SomeResource();
|
|
SomeResource.bar(res);
|
|
}
|
|
|
|
void skippedVritualCallDoesNotCloseResourceOnReceiver() {
|
|
SomeResource res = new SomeResource();
|
|
res.foo(42);
|
|
}
|
|
|
|
}
|