From f2b041dce0b855ecc7eec6514b5b0c3785378855 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Thu, 26 Jul 2018 15:54:18 -0700 Subject: [PATCH] Fix data source for HEIF exif extractor Do not allow the source to read past available bytes, since the underlying input stream may not be able to seek after that. For input streams from files, the available bytes is usually the file size, and we usually don't have problem when the file is of decent size. But when the file is very small, some of the extractors (other than mp4) would request bytes past the end of the file, which goes over the available range. Once that condition is hit, we can't reset to the offet needed for mp4 extractor and heif parsing would fail. bug: 111897855 bug: 117625929 test: open heic files of various sizes in Files (Downloads) app, check that ExifInterface shouldn't encounter any exceptions. Change-Id: I668ff900f4155dc310cb7ea8977bbe091791c5d7 --- media/java/android/media/ExifInterface.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index a959759b78de5..2395b24f7136b 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -2545,7 +2545,9 @@ public class ExifInterface { if (size == 0) { return 0; } - if (position < 0) { + // We don't allow read positions after the available bytes, + // the input stream won't be able to seek back then. + if (position < 0 || position >= in.available()) { return -1; } try { @@ -2554,6 +2556,13 @@ public class ExifInterface { mPosition = position; } + // If the read will cause us to go over the available bytes, + // reduce the size so that we stay in the available range. + // Otherwise the input stream may not be able to seek back. + if (mPosition + size > in.available()) { + size = in.available() - (int)mPosition; + } + int bytesRead = in.read(buffer, offset, size); if (bytesRead >= 0) { mPosition += bytesRead;