Loading media/java/android/media/ExifInterface.java +38 −14 Original line number Diff line number Diff line Loading @@ -1222,7 +1222,7 @@ public class ExifInterface { TAG_F_NUMBER, TAG_DIGITAL_ZOOM_RATIO, TAG_EXPOSURE_TIME, TAG_SUBJECT_DISTANCE, TAG_GPS_TIMESTAMP)); // Mappings from tag number to IFD type for pointer tags. private static final HashMap sExifPointerTagMap = new HashMap(); private static final HashMap<Integer, Integer> sExifPointerTagMap = new HashMap(); // See JPEG File Interchange Format Version 1.02. // The following values are defined for handling JPEG streams. In this implementation, we are Loading Loading @@ -1299,6 +1299,7 @@ public class ExifInterface { private final boolean mIsInputStream; private int mMimeType; private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length]; private Set<Integer> mAttributesOffsets = new HashSet<>(EXIF_TAGS.length); private ByteOrder mExifByteOrder = ByteOrder.BIG_ENDIAN; private boolean mHasThumbnail; // The following values used for indicating a thumbnail position. Loading Loading @@ -2957,8 +2958,9 @@ public class ExifInterface { } // See TIFF 6.0 Section 2: TIFF Structure, Figure 1. short numberOfDirectoryEntry = dataInputStream.readShort(); if (dataInputStream.mPosition + 12 * numberOfDirectoryEntry > dataInputStream.mLength) { // Return if the size of entries is too big. if (dataInputStream.mPosition + 12 * numberOfDirectoryEntry > dataInputStream.mLength || numberOfDirectoryEntry <= 0) { // Return if the size of entries is either too big or negative. return; } Loading Loading @@ -3049,7 +3051,7 @@ public class ExifInterface { } // Recursively parse IFD when a IFD pointer tag appears. Object nextIfdType = sExifPointerTagMap.get(tagNumber); Integer nextIfdType = sExifPointerTagMap.get(tagNumber); if (DEBUG) { Log.d(TAG, "nextIfdType: " + nextIfdType + " byteCount: " + byteCount); } Loading Loading @@ -3083,9 +3085,20 @@ public class ExifInterface { if (DEBUG) { Log.d(TAG, String.format("Offset: %d, tagName: %s", offset, tag.name)); } // Check if the next IFD offset // 1. Exists within the boundaries of the input stream // 2. Does not point to a previously read IFD. if (offset > 0L && offset < dataInputStream.mLength) { if (!mAttributesOffsets.contains((int) offset)) { // Save offset of current IFD to prevent reading an IFD that is already read mAttributesOffsets.add(dataInputStream.mPosition); dataInputStream.seek(offset); readImageFileDirectory(dataInputStream, (int) nextIfdType); readImageFileDirectory(dataInputStream, nextIfdType); } else { Log.w(TAG, "Skip jump into the IFD since it has already been read: " + "IfdType " + nextIfdType + " (at " + offset + ")"); } } else { Log.w(TAG, "Skip jump into the IFD since its offset is invalid: " + offset); } Loading Loading @@ -3127,16 +3140,27 @@ public class ExifInterface { if (DEBUG) { Log.d(TAG, String.format("nextIfdOffset: %d", nextIfdOffset)); } // The next IFD offset needs to be bigger than 8 // since the first IFD offset is at least 8. if (nextIfdOffset > 8 && nextIfdOffset < dataInputStream.mLength) { // Check if the next IFD offset // 1. Exists within the boundaries of the input stream // 2. Does not point to a previously read IFD. if (nextIfdOffset > 0L && nextIfdOffset < dataInputStream.mLength) { if (!mAttributesOffsets.contains(nextIfdOffset)) { // Save offset of current IFD to prevent reading an IFD that is already read. mAttributesOffsets.add(dataInputStream.mPosition); dataInputStream.seek(nextIfdOffset); if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) { // Do not overwrite thumbnail IFD data if it alreay exists. if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) { readImageFileDirectory(dataInputStream, IFD_TYPE_THUMBNAIL); } else if (mAttributes[IFD_TYPE_PREVIEW].isEmpty()) { readImageFileDirectory(dataInputStream, IFD_TYPE_PREVIEW); } } else { Log.w(TAG, "Stop reading file since re-reading an IFD may cause an " + "infinite loop: " + nextIfdOffset); } } else { Log.w(TAG, "Stop reading file since a wrong offset may cause an infinite loop: " + nextIfdOffset); } } } Loading Loading
media/java/android/media/ExifInterface.java +38 −14 Original line number Diff line number Diff line Loading @@ -1222,7 +1222,7 @@ public class ExifInterface { TAG_F_NUMBER, TAG_DIGITAL_ZOOM_RATIO, TAG_EXPOSURE_TIME, TAG_SUBJECT_DISTANCE, TAG_GPS_TIMESTAMP)); // Mappings from tag number to IFD type for pointer tags. private static final HashMap sExifPointerTagMap = new HashMap(); private static final HashMap<Integer, Integer> sExifPointerTagMap = new HashMap(); // See JPEG File Interchange Format Version 1.02. // The following values are defined for handling JPEG streams. In this implementation, we are Loading Loading @@ -1299,6 +1299,7 @@ public class ExifInterface { private final boolean mIsInputStream; private int mMimeType; private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length]; private Set<Integer> mAttributesOffsets = new HashSet<>(EXIF_TAGS.length); private ByteOrder mExifByteOrder = ByteOrder.BIG_ENDIAN; private boolean mHasThumbnail; // The following values used for indicating a thumbnail position. Loading Loading @@ -2957,8 +2958,9 @@ public class ExifInterface { } // See TIFF 6.0 Section 2: TIFF Structure, Figure 1. short numberOfDirectoryEntry = dataInputStream.readShort(); if (dataInputStream.mPosition + 12 * numberOfDirectoryEntry > dataInputStream.mLength) { // Return if the size of entries is too big. if (dataInputStream.mPosition + 12 * numberOfDirectoryEntry > dataInputStream.mLength || numberOfDirectoryEntry <= 0) { // Return if the size of entries is either too big or negative. return; } Loading Loading @@ -3049,7 +3051,7 @@ public class ExifInterface { } // Recursively parse IFD when a IFD pointer tag appears. Object nextIfdType = sExifPointerTagMap.get(tagNumber); Integer nextIfdType = sExifPointerTagMap.get(tagNumber); if (DEBUG) { Log.d(TAG, "nextIfdType: " + nextIfdType + " byteCount: " + byteCount); } Loading Loading @@ -3083,9 +3085,20 @@ public class ExifInterface { if (DEBUG) { Log.d(TAG, String.format("Offset: %d, tagName: %s", offset, tag.name)); } // Check if the next IFD offset // 1. Exists within the boundaries of the input stream // 2. Does not point to a previously read IFD. if (offset > 0L && offset < dataInputStream.mLength) { if (!mAttributesOffsets.contains((int) offset)) { // Save offset of current IFD to prevent reading an IFD that is already read mAttributesOffsets.add(dataInputStream.mPosition); dataInputStream.seek(offset); readImageFileDirectory(dataInputStream, (int) nextIfdType); readImageFileDirectory(dataInputStream, nextIfdType); } else { Log.w(TAG, "Skip jump into the IFD since it has already been read: " + "IfdType " + nextIfdType + " (at " + offset + ")"); } } else { Log.w(TAG, "Skip jump into the IFD since its offset is invalid: " + offset); } Loading Loading @@ -3127,16 +3140,27 @@ public class ExifInterface { if (DEBUG) { Log.d(TAG, String.format("nextIfdOffset: %d", nextIfdOffset)); } // The next IFD offset needs to be bigger than 8 // since the first IFD offset is at least 8. if (nextIfdOffset > 8 && nextIfdOffset < dataInputStream.mLength) { // Check if the next IFD offset // 1. Exists within the boundaries of the input stream // 2. Does not point to a previously read IFD. if (nextIfdOffset > 0L && nextIfdOffset < dataInputStream.mLength) { if (!mAttributesOffsets.contains(nextIfdOffset)) { // Save offset of current IFD to prevent reading an IFD that is already read. mAttributesOffsets.add(dataInputStream.mPosition); dataInputStream.seek(nextIfdOffset); if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) { // Do not overwrite thumbnail IFD data if it alreay exists. if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) { readImageFileDirectory(dataInputStream, IFD_TYPE_THUMBNAIL); } else if (mAttributes[IFD_TYPE_PREVIEW].isEmpty()) { readImageFileDirectory(dataInputStream, IFD_TYPE_PREVIEW); } } else { Log.w(TAG, "Stop reading file since re-reading an IFD may cause an " + "infinite loop: " + nextIfdOffset); } } else { Log.w(TAG, "Stop reading file since a wrong offset may cause an infinite loop: " + nextIfdOffset); } } } Loading