From 5c32b6da4400c85db2245de3bc18c91d495ce1c5 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Tue, 13 Nov 2012 16:28:57 +0900 Subject: [PATCH] Make sure all FDs are correctly closed. In this kind of series of calls, it's possible that an outer call to a constructor fails, but the inner succeeded. Example: try { is = new A(new B()); } finally { if (null != is) is.close(); } In this case, if new B() succeeds but new A() throws an exception, is stays null and the intermediate object is never closed. This is what was happening in this instance. Bug: 7377336 Change-Id: I3fae9fec1135244982fcf5098c76d93f3e0f2add --- .../latin/BinaryDictionaryFileDumper.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java index b0b65edb6..9a3f88f52 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java @@ -154,6 +154,9 @@ public final class BinaryDictionaryFileDumper { for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) { InputStream originalSourceStream = null; InputStream inputStream = null; + InputStream uncompressedStream = null; + InputStream decryptedStream = null; + BufferedInputStream bufferedStream = null; File outputFile = null; FileOutputStream outputStream = null; AssetFileDescriptor afd = null; @@ -173,18 +176,19 @@ public final class BinaryDictionaryFileDumper { // Get the appropriate decryption method for this try switch (mode) { case COMPRESSED_CRYPTED_COMPRESSED: - inputStream = FileTransforms.getUncompressedStream( - FileTransforms.getDecryptedStream( - FileTransforms.getUncompressedStream( - originalSourceStream))); + uncompressedStream = + FileTransforms.getUncompressedStream(originalSourceStream); + decryptedStream = FileTransforms.getDecryptedStream(uncompressedStream); + inputStream = FileTransforms.getUncompressedStream(decryptedStream); break; case CRYPTED_COMPRESSED: - inputStream = FileTransforms.getUncompressedStream( - FileTransforms.getDecryptedStream(originalSourceStream)); + decryptedStream = FileTransforms.getDecryptedStream(originalSourceStream); + inputStream = FileTransforms.getUncompressedStream(decryptedStream); break; case COMPRESSED_CRYPTED: - inputStream = FileTransforms.getDecryptedStream( - FileTransforms.getUncompressedStream(originalSourceStream)); + uncompressedStream = + FileTransforms.getUncompressedStream(originalSourceStream); + inputStream = FileTransforms.getDecryptedStream(uncompressedStream); break; case COMPRESSED_ONLY: inputStream = FileTransforms.getUncompressedStream(originalSourceStream); @@ -195,8 +199,9 @@ public final class BinaryDictionaryFileDumper { case NONE: inputStream = originalSourceStream; break; - } - checkMagicAndCopyFileTo(new BufferedInputStream(inputStream), outputStream); + } + bufferedStream = new BufferedInputStream(inputStream); + checkMagicAndCopyFileTo(bufferedStream, outputStream); outputStream.flush(); outputStream.close(); final File finalFile = new File(finalFileName); @@ -228,8 +233,11 @@ public final class BinaryDictionaryFileDumper { try { // inputStream.close() will close afd, we should not call afd.close(). if (null != inputStream) inputStream.close(); + if (null != uncompressedStream) uncompressedStream.close(); + if (null != decryptedStream) decryptedStream.close(); + if (null != bufferedStream) bufferedStream.close(); } catch (Exception e) { - Log.e(TAG, "Exception while closing a cross-process file descriptor : " + e); + Log.e(TAG, "Exception while closing a file descriptor : " + e); } try { if (null != outputStream) outputStream.close();