From 0b49f5725cabd64d27960b1b017e5c009f701cf8 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Tue, 23 Jan 2018 11:38:23 -0500 Subject: [PATCH] Do not close InputStream from InputStreamSource Test: I28f82285c0341aff7192eb0157e0de4b97cda577 This is called by public methods that pass along an InputStream. As such, it is possible that the client was planning to continue reading from the InputStream, so do not close it. Change-Id: Iaa53c44d578c1311315616c8fd931bed40290a92 --- .../java/android/graphics/ImageDecoder.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 02d22bec58287..44d47f98f3abb 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -148,7 +148,7 @@ public final class ImageDecoder implements AutoCloseable { throw new FileNotFoundException(mUri.toString()); } - return createFromStream(is); + return createFromStream(is, true); } final FileDescriptor fd = assetFd.getFileDescriptor(); @@ -160,7 +160,7 @@ public final class ImageDecoder implements AutoCloseable { Os.lseek(fd, offset, SEEK_SET); decoder = nCreate(fd); } catch (ErrnoException e) { - decoder = createFromStream(new FileInputStream(fd)); + decoder = createFromStream(new FileInputStream(fd), true); } } finally { if (decoder == null) { @@ -180,7 +180,7 @@ public final class ImageDecoder implements AutoCloseable { try { Os.lseek(fd, 0, SEEK_CUR); } catch (ErrnoException e) { - return createFromStream(stream); + return createFromStream(stream, true); } ImageDecoder decoder = null; @@ -191,13 +191,15 @@ public final class ImageDecoder implements AutoCloseable { IoUtils.closeQuietly(stream); } else { decoder.mInputStream = stream; + decoder.mOwnsInputStream = true; } } return decoder; } @NonNull - private static ImageDecoder createFromStream(@NonNull InputStream is) throws IOException { + private static ImageDecoder createFromStream(@NonNull InputStream is, + boolean closeInputStream) throws IOException { // Arbitrary size matches BitmapFactory. byte[] storage = new byte[16 * 1024]; ImageDecoder decoder = null; @@ -205,9 +207,12 @@ public final class ImageDecoder implements AutoCloseable { decoder = nCreate(is, storage); } finally { if (decoder == null) { - IoUtils.closeQuietly(is); + if (closeInputStream) { + IoUtils.closeQuietly(is); + } } else { decoder.mInputStream = is; + decoder.mOwnsInputStream = closeInputStream; decoder.mTempStorage = storage; } } @@ -215,6 +220,9 @@ public final class ImageDecoder implements AutoCloseable { return decoder; } + /** + * For backwards compatibility, this does *not* close the InputStream. + */ private static class InputStreamSource extends Source { InputStreamSource(Resources res, InputStream is, int inputDensity) { if (is == null) { @@ -244,7 +252,7 @@ public final class ImageDecoder implements AutoCloseable { } InputStream is = mInputStream; mInputStream = null; - return createFromStream(is); + return createFromStream(is, false); } } } @@ -293,6 +301,7 @@ public final class ImageDecoder implements AutoCloseable { IoUtils.closeQuietly(is); } else { decoder.mInputStream = is; + decoder.mOwnsInputStream = true; } } return decoder; @@ -426,6 +435,7 @@ public final class ImageDecoder implements AutoCloseable { // Objects for interacting with the input. private InputStream mInputStream; + private boolean mOwnsInputStream; private byte[] mTempStorage; private AssetFileDescriptor mAssetFd; private final AtomicBoolean mClosed = new AtomicBoolean(); @@ -797,7 +807,9 @@ public final class ImageDecoder implements AutoCloseable { nClose(mNativePtr); mNativePtr = 0; - IoUtils.closeQuietly(mInputStream); + if (mOwnsInputStream) { + IoUtils.closeQuietly(mInputStream); + } IoUtils.closeQuietly(mAssetFd); mInputStream = null;