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
main
Jean Chalard 2012-11-13 16:28:57 +09:00
parent bc43e3f290
commit 5c32b6da44
1 changed files with 19 additions and 11 deletions

View File

@ -154,6 +154,9 @@ public final class BinaryDictionaryFileDumper {
for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) { for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
InputStream originalSourceStream = null; InputStream originalSourceStream = null;
InputStream inputStream = null; InputStream inputStream = null;
InputStream uncompressedStream = null;
InputStream decryptedStream = null;
BufferedInputStream bufferedStream = null;
File outputFile = null; File outputFile = null;
FileOutputStream outputStream = null; FileOutputStream outputStream = null;
AssetFileDescriptor afd = null; AssetFileDescriptor afd = null;
@ -173,18 +176,19 @@ public final class BinaryDictionaryFileDumper {
// Get the appropriate decryption method for this try // Get the appropriate decryption method for this try
switch (mode) { switch (mode) {
case COMPRESSED_CRYPTED_COMPRESSED: case COMPRESSED_CRYPTED_COMPRESSED:
inputStream = FileTransforms.getUncompressedStream( uncompressedStream =
FileTransforms.getDecryptedStream( FileTransforms.getUncompressedStream(originalSourceStream);
FileTransforms.getUncompressedStream( decryptedStream = FileTransforms.getDecryptedStream(uncompressedStream);
originalSourceStream))); inputStream = FileTransforms.getUncompressedStream(decryptedStream);
break; break;
case CRYPTED_COMPRESSED: case CRYPTED_COMPRESSED:
inputStream = FileTransforms.getUncompressedStream( decryptedStream = FileTransforms.getDecryptedStream(originalSourceStream);
FileTransforms.getDecryptedStream(originalSourceStream)); inputStream = FileTransforms.getUncompressedStream(decryptedStream);
break; break;
case COMPRESSED_CRYPTED: case COMPRESSED_CRYPTED:
inputStream = FileTransforms.getDecryptedStream( uncompressedStream =
FileTransforms.getUncompressedStream(originalSourceStream)); FileTransforms.getUncompressedStream(originalSourceStream);
inputStream = FileTransforms.getDecryptedStream(uncompressedStream);
break; break;
case COMPRESSED_ONLY: case COMPRESSED_ONLY:
inputStream = FileTransforms.getUncompressedStream(originalSourceStream); inputStream = FileTransforms.getUncompressedStream(originalSourceStream);
@ -195,8 +199,9 @@ public final class BinaryDictionaryFileDumper {
case NONE: case NONE:
inputStream = originalSourceStream; inputStream = originalSourceStream;
break; break;
} }
checkMagicAndCopyFileTo(new BufferedInputStream(inputStream), outputStream); bufferedStream = new BufferedInputStream(inputStream);
checkMagicAndCopyFileTo(bufferedStream, outputStream);
outputStream.flush(); outputStream.flush();
outputStream.close(); outputStream.close();
final File finalFile = new File(finalFileName); final File finalFile = new File(finalFileName);
@ -228,8 +233,11 @@ public final class BinaryDictionaryFileDumper {
try { try {
// inputStream.close() will close afd, we should not call afd.close(). // inputStream.close() will close afd, we should not call afd.close().
if (null != inputStream) inputStream.close(); if (null != inputStream) inputStream.close();
if (null != uncompressedStream) uncompressedStream.close();
if (null != decryptedStream) decryptedStream.close();
if (null != bufferedStream) bufferedStream.close();
} catch (Exception e) { } 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 { try {
if (null != outputStream) outputStream.close(); if (null != outputStream) outputStream.close();