Bug 1356693 - infer: fix RESOURCE_LEAK's in geckoview r=walkingice

Similar to some previous commits, we prefer non-throwing constructors
in order to ensure we never lose a reference to an unclosed stream.
InpuStreamReader(..., Charset) is preferred over InputStreamReader(..., String)
since the latter can throw when the String is not a valid Charset.
(In reality we know that our Charset Strings are correct, but the compiler
 isn't able to determine that for itself. Moreover, using the preparsed
 Charset is more efficient.)

MozReview-Commit-ID: 9z07G3hqPI3

--HG--
extra : rebase_source : 6ed740bf5a1e5296bd2afe5c58b19a43acab0647
This commit is contained in:
Andrzej Hunt 2017-04-26 17:22:30 +08:00
Родитель 1f9929fe75
Коммит d8e202e0c6
4 изменённых файлов: 53 добавлений и 41 удалений

Просмотреть файл

@ -23,7 +23,6 @@ import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import android.annotation.SuppressLint;
import org.mozilla.gecko.annotation.JNITarget;
@ -31,13 +30,11 @@ import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.gfx.BitmapUtils;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.gfx.PanZoomController;
import org.mozilla.gecko.permissions.Permissions;
import org.mozilla.gecko.process.GeckoProcessManager;
import org.mozilla.gecko.process.GeckoServiceChildProcess;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.HardwareCodecCapabilityUtils;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.IOUtils;
import org.mozilla.gecko.util.ProxySelector;
import org.mozilla.gecko.util.ThreadUtils;
@ -1206,11 +1203,14 @@ public class GeckoAppShell
int pidColumn = -1;
int userColumn = -1;
Process ps = null;
InputStreamReader inputStreamReader = null;
BufferedReader in = null;
try {
// run ps and parse its output
java.lang.Process ps = Runtime.getRuntime().exec("ps");
BufferedReader in = new BufferedReader(new InputStreamReader(ps.getInputStream()),
2048);
ps = Runtime.getRuntime().exec("ps");
inputStreamReader = new InputStreamReader(ps.getInputStream());
in = new BufferedReader(inputStreamReader, 2048);
String headerOutput = in.readLine();
@ -1242,10 +1242,14 @@ public class GeckoAppShell
break;
}
}
in.close();
}
catch (Exception e) {
} catch (Exception e) {
Log.w(LOGTAG, "Failed to enumerate Gecko processes.", e);
} finally {
IOUtils.safeStreamClose(in);
IOUtils.safeStreamClose(inputStreamReader);
if (ps != null) {
ps.destroy();
}
}
}
@ -1261,11 +1265,7 @@ public class GeckoAppShell
} catch (Exception ex) {
return "";
} finally {
if (null != cmdlineReader) {
try {
cmdlineReader.close();
} catch (Exception e) { }
}
IOUtils.safeStreamClose(cmdlineReader);
}
}
@ -1273,13 +1273,17 @@ public class GeckoAppShell
int pidColumn = -1;
int nameColumn = -1;
// run lsof and parse its output
Process process = null;
InputStreamReader inputStreamReader = null;
BufferedReader in = null;
try {
String filter = GeckoProfile.get(getApplicationContext()).getDir().toString();
Log.d(LOGTAG, "[OPENFILE] Filter: " + filter);
// run lsof and parse its output
java.lang.Process lsof = Runtime.getRuntime().exec("lsof");
BufferedReader in = new BufferedReader(new InputStreamReader(lsof.getInputStream()), 2048);
process = Runtime.getRuntime().exec("lsof");
inputStreamReader = new InputStreamReader(process.getInputStream());
in = new BufferedReader(inputStreamReader, 2048);
String headerOutput = in.readLine();
StringTokenizer st = new StringTokenizer(headerOutput);
@ -1310,8 +1314,14 @@ public class GeckoAppShell
if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(file) && file.startsWith(filter))
Log.d(LOGTAG, "[OPENFILE] " + name + "(" + split[pidColumn] + ") : " + file);
}
in.close();
} catch (Exception e) { }
} catch (Exception e) {
} finally {
IOUtils.safeStreamClose(in);
IOUtils.safeStreamClose(inputStreamReader);
if (process != null) {
process.destroy();
}
}
}
@WrapForJNI(calledFrom = "gecko")
@ -2087,14 +2097,16 @@ public class GeckoAppShell
final PipedOutputStream output = new PipedOutputStream();
connect(output);
ThreadUtils.postToBackgroundThread(
new Runnable() {
@Override
public void run() {
try {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
output.close();
} catch (IOException ioe) { }
} finally {
IOUtils.safeStreamClose(output);
}
}
});
mHaveConnected = true;

Просмотреть файл

@ -145,25 +145,26 @@ public class FileUtils {
*/
public static String readStringFromInputStreamAndCloseStream(final InputStream inputStream, final int bufferSize)
throws IOException {
if (bufferSize <= 0) {
// Safe close: it's more important to alert the programmer of
// their error than to let them catch and continue on their way.
IOUtils.safeStreamClose(inputStream);
throw new IllegalArgumentException("Expected buffer size larger than 0. Got: " + bufferSize);
}
final StringBuilder stringBuilder = new StringBuilder(bufferSize);
final InputStreamReader reader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
InputStreamReader reader = null;
try {
if (bufferSize <= 0) {
throw new IllegalArgumentException("Expected buffer size larger than 0. Got: " + bufferSize);
}
final StringBuilder stringBuilder = new StringBuilder(bufferSize);
reader = new InputStreamReader(inputStream, StringUtils.UTF_8);
int charsRead;
final char[] buffer = new char[bufferSize];
while ((charsRead = reader.read(buffer, 0, bufferSize)) != -1) {
stringBuilder.append(buffer, 0, charsRead);
}
return stringBuilder.toString();
} finally {
reader.close();
IOUtils.safeStreamClose(reader);
IOUtils.safeStreamClose(inputStream);
}
return stringBuilder.toString();
}
/**

Просмотреть файл

@ -45,12 +45,13 @@ public final class INIParser extends INISection {
e1.printStackTrace();
}
BufferedWriter writer = new BufferedWriter(outputStream);
final BufferedWriter writer = new BufferedWriter(outputStream);
try {
write(writer);
writer.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.safeStreamClose(writer);
}
}

Просмотреть файл

@ -28,12 +28,10 @@ class PublicSuffixPatterns {
EXACT = new HashSet<>();
InputStream stream = null;
BufferedReader reader = null;
try {
stream = context.getAssets().open("publicsuffixlist");
BufferedReader reader = new BufferedReader(new InputStreamReader(
new BufferedInputStream(stream)));
reader = new BufferedReader(new InputStreamReader(
new BufferedInputStream(context.getAssets().open("publicsuffixlist"))));
String line;
while ((line = reader.readLine()) != null) {
@ -43,7 +41,7 @@ class PublicSuffixPatterns {
} catch (IOException e) {
Log.e("Patterns", "IOException during loading public suffix list");
} finally {
IOUtils.safeStreamClose(stream);
IOUtils.safeStreamClose(reader);
}
return EXACT;