Bug 1474928: Close files and connections. draft
authorRobert Bartlensky <rbartlensky@mozilla.com>
Wed, 11 Jul 2018 16:54:35 +0100
changeset 816934 950a912da17caad6191181edb402d6be0907adef
parent 816856 aff060ad3204234adae2d59b3776207c6687ebfc
push id115887
push userbmo:rbartlensky@mozilla.com
push dateWed, 11 Jul 2018 16:33:39 +0000
bugs1474928
milestone63.0a1
Bug 1474928: Close files and connections. MozReview-Commit-ID: DZ6kzl7Lcf4
mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterService.java
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterService.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterService.java
@@ -81,31 +81,52 @@ public class CrashReporterService extend
             return null;
         }
     }
 
     private boolean moveFile(File inFile, File outFile) {
         Log.i(LOGTAG, "moving " + inFile + " to " + outFile);
         if (inFile.renameTo(outFile))
             return true;
+        FileInputStream inStream = null;
+        FileOutputStream outStream = null;
         try {
             outFile.createNewFile();
             Log.i(LOGTAG, "couldn't rename minidump file");
             // so copy it instead
-            FileChannel inChannel = new FileInputStream(inFile).getChannel();
-            FileChannel outChannel = new FileOutputStream(outFile).getChannel();
+            inStream = new FileInputStream(inFile);
+            outStream = new FileOutputStream(outFile);
+            FileChannel inChannel = inStream.getChannel();
+            FileChannel outChannel = outStream.getChannel();
             long transferred = inChannel.transferTo(0, inChannel.size(), outChannel);
-            inChannel.close();
-            outChannel.close();
-
             if (transferred > 0)
                 inFile.delete();
         } catch (Exception e) {
             Log.e(LOGTAG, "exception while copying minidump file: ", e);
             return false;
+        } finally {
+            // always try and close inStream and outStream while taking into
+            // consideration that `.close` throws as well.
+            try {
+                if (inStream != null) {
+                    inStream.close();
+                }
+            } catch (IOException e) {
+                Log.e(LOGTAG, "inStream could not be closed: ", e);
+                return false;
+            } finally {
+                try {
+                    if (outStream != null) {
+                        outStream.close();
+                    }
+                } catch (IOException e) {
+                    Log.e(LOGTAG, "outStream could not be closed: ", e);
+                    return false;
+                }
+            }
         }
         return true;
     }
 
     private void submitCrash(Intent intent) {
         mMinidumpSucceeded = intent.getBooleanExtra(PASSED_MINI_DUMP_SUCCESS_KEY, false);
         if (!mMinidumpSucceeded) {
             Log.i(LOGTAG, "Failed to get minidump.");
@@ -227,22 +248,33 @@ public class CrashReporterService extend
                 writer.close();
             }
         } catch (Exception e) {
             Log.e(LOGTAG, "exception while computing the minidump hash: ", e);
         }
     }
 
     private boolean readStringsFromFile(String filePath, Map<String, String> stringMap) {
+        FileReader fileReader = null;
         try {
-            BufferedReader reader = new BufferedReader(new FileReader(filePath));
+            fileReader = new FileReader(filePath);
+            BufferedReader reader = new BufferedReader(fileReader);
             return readStringsFromReader(reader, stringMap);
         } catch (Exception e) {
             Log.e(LOGTAG, "exception while reading strings: ", e);
             return false;
+        } finally {
+            try {
+                if (fileReader != null) {
+                    fileReader.close();
+                }
+            } catch (IOException e) {
+                Log.e(LOGTAG, "exception while closing file: ", e);
+                return false;
+            }
         }
     }
 
     private boolean readStringsFromReader(BufferedReader reader, Map<String, String> stringMap) throws IOException {
         String line;
         while ((line = reader.readLine()) != null) {
             int equalsPos = -1;
             if ((equalsPos = line.indexOf('=')) != -1) {
@@ -288,23 +320,23 @@ public class CrashReporterService extend
 
     private void sendReport(File minidumpFile, Map<String, String> extras, File extrasFile) {
         Log.i(LOGTAG, "sendReport: " + minidumpFile.getPath());
 
         String spec = extras.get(SERVER_URL_KEY);
         if (spec == null) {
             return;
         }
-
+        HttpURLConnection conn = null;
         try {
             final URL url = new URL(URLDecoder.decode(spec, "UTF-8"));
             final URI uri = new URI(url.getProtocol(), url.getUserInfo(),
                     url.getHost(), url.getPort(),
                     url.getPath(), url.getQuery(), url.getRef());
-            HttpURLConnection conn = (HttpURLConnection) ProxySelector.openConnectionWithProxy(uri);
+            conn = (HttpURLConnection) ProxySelector.openConnectionWithProxy(uri);
             conn.setRequestMethod("POST");
             String boundary = generateBoundary();
             conn.setDoOutput(true);
             conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
             conn.setRequestProperty("Content-Encoding", "gzip");
 
             OutputStream os = new GZIPOutputStream(conn.getOutputStream());
             for (String key : extras.keySet()) {
@@ -361,15 +393,19 @@ public class CrashReporterService extend
                 Log.i(LOGTAG, "Successfully sent crash report: " + crashid);
             } else {
                 Log.w(LOGTAG, "Received failure HTTP response code from server: " + conn.getResponseCode());
             }
         } catch (IOException e) {
             Log.e(LOGTAG, "exception during send: ", e);
         } catch (URISyntaxException e) {
             Log.e(LOGTAG, "exception during new URI: ", e);
+        } finally {
+            if (conn != null) {
+                conn.disconnect();
+            }
         }
     }
 
     private String unescape(String string) {
         return string.replaceAll("\\\\\\\\", "\\").replaceAll("\\\\n", "\n").replaceAll("\\\\t", "\t");
     }
 }