OSDN Git Service

Fix offset and ASCII type handling in exif.
authorRuben Brunk <rubenbrunk@google.com>
Thu, 25 Apr 2013 20:10:53 +0000 (13:10 -0700)
committerRuben Brunk <rubenbrunk@google.com>
Thu, 25 Apr 2013 20:10:53 +0000 (13:10 -0700)
Bug: 8713891
Change-Id: I8adaf1bc42eea2cda741d149de5f1a64c3e4c74c

gallerycommon/src/com/android/gallery3d/exif/ExifParser.java
gallerycommon/src/com/android/gallery3d/exif/ExifTag.java

index b6d7e61..5467d42 100644 (file)
@@ -510,7 +510,9 @@ class ExifParser {
      * @see #EVENT_VALUE_OF_REGISTERED_TAG
      */
     protected void registerForTagValue(ExifTag tag) {
-        mCorrespondingEvent.put(tag.getOffset(), new ExifTagEvent(tag, true));
+        if (tag.getOffset() >= mTiffStream.getReadByteCount()) {
+            mCorrespondingEvent.put(tag.getOffset(), new ExifTagEvent(tag, true));
+        }
     }
 
     private void registerIfd(int ifdType, long offset) {
@@ -563,7 +565,12 @@ class ExifParser {
                 tag.setOffset((int) offset);
             }
         } else {
+            boolean defCount = tag.hasDefinedCount();
+            // Set defined count to 0 so we can add \0 to non-terminated strings
+            tag.setHasDefinedCount(false);
+            // Read value
             readFullTagValue(tag);
+            tag.setHasDefinedCount(defCount);
             mTiffStream.skip(4 - dataSize);
             // Set the offset to the position of value.
             tag.setOffset(mTiffStream.getReadByteCount() - 4);
@@ -644,13 +651,22 @@ class ExifParser {
             if (mCorrespondingEvent.size() > 0) {
                 if (mCorrespondingEvent.firstEntry().getKey() < mTiffStream.getReadByteCount()
                         + size) {
-                    if (mCorrespondingEvent.firstEntry().getValue() instanceof ImageEvent) {
-                        // Invalid thumbnail offset: tag metadata overlaps with
-                        // strip.
+                    Object event = mCorrespondingEvent.firstEntry().getValue();
+                    if (event instanceof ImageEvent) {
+                        // Tag value overlaps thumbnail, ignore thumbnail.
+                        Log.w(TAG, "Thumbnail overlaps value for tag: \n" + tag.toString());
                         Entry<Integer, Object> entry = mCorrespondingEvent.pollFirstEntry();
-                        // Ignore thumbnail.
                         Log.w(TAG, "Invalid thumbnail offset: " + entry.getKey());
                     } else {
+                        // Tag value overlaps another tag, shorten count
+                        if (event instanceof IfdEvent) {
+                            Log.w(TAG, "Ifd " + ((IfdEvent) event).ifd
+                                    + " overlaps value for tag: \n" + tag.toString());
+                        } else if (event instanceof ExifTagEvent) {
+                            Log.w(TAG, "Tag value for tag: \n"
+                                    + ((ExifTagEvent) event).tag.toString()
+                                    + " overlaps value for tag: \n" + tag.toString());
+                        }
                         size = mCorrespondingEvent.firstEntry().getKey()
                                 - mTiffStream.getReadByteCount();
                         Log.w(TAG, "Invalid size of tag: \n" + tag.toString()
index 24e7f53..b8b3872 100644 (file)
@@ -330,8 +330,13 @@ public class ExifTag {
         }
 
         byte[] buf = value.getBytes(US_ASCII);
-        byte[] finalBuf = (buf[buf.length - 1] == 0 || mDataType == TYPE_UNDEFINED) ? buf : Arrays
+        byte[] finalBuf = buf;
+        if (buf.length > 0) {
+            finalBuf = (buf[buf.length - 1] == 0 || mDataType == TYPE_UNDEFINED) ? buf : Arrays
                 .copyOf(buf, buf.length + 1);
+        } else if (mDataType == TYPE_ASCII && mComponentCountActual == 1) {
+            finalBuf = new byte[] { 0 };
+        }
         int count = finalBuf.length;
         if (checkBadComponentCount(count)) {
             return false;
@@ -870,6 +875,10 @@ public class ExifTag {
         mHasDefinedDefaultComponentCount = d;
     }
 
+    protected boolean hasDefinedCount() {
+        return mHasDefinedDefaultComponentCount;
+    }
+
     private boolean checkBadComponentCount(int count) {
         if (mHasDefinedDefaultComponentCount && (mComponentCountActual != count)) {
             return true;