[ 
https://issues.apache.org/jira/browse/SANSELAN-55?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13128978#comment-13128978
 ] 

Damjan Jovanovic commented on SANSELAN-55:
------------------------------------------

JpegImageParser.getMetadata() calls JpegImageParser.getExifMetadata(), which 
reads the EXIF section as below:

ByteSourceFile byteSource = new ByteSourceFile(new 
File("/home/user/Downloads/stupidpic.jpg"));
byte[] block = new JpegImageParser().getExifRawData(byteSource);
FileOutputStream fos = new FileOutputStream("/tmp/block.tiff");
fos.write(block);
fos.close();

That EXIF section/TIFF file is 248 bytes long.

$ file /tmp/block.tiff 
/tmp/block.tiff: TIFF image data, little-endian

$ tiffinfo /tmp/block.tiff
TIFFReadDirectory: Warning, /tmp/block.tiff: invalid TIFF directory; tags are 
not sorted in ascending order.
TIFFReadDirectory: Warning, /tmp/block.tiff: unknown field with tag 37385 
(0x9209) encountered.
TIFFReadDirectory: Warning, /tmp/block.tiff: unknown field with tag 37384 
(0x9208) encountered.
TIFFReadDirectory: Warning, /tmp/block.tiff: unknown field with tag 36868 
(0x9004) encountered.
TIFFReadDirectory: Warning, /tmp/block.tiff: unknown field with tag 37383 
(0x9207) encountered.
TIFFReadDirectory: Warning, /tmp/block.tiff: unknown field with tag 41987 
(0xa403) encountered.
TIFFReadDirectory: Warning, /tmp/block.tiff: unknown field with tag 218 (0xda) 
encountered.
MissingRequired: /tmp/block.tiff: TIFF directory is missing required 
"StripOffsets" field.

Bad news, but maybe it's still usable...

Next, JpegImageParser.getExifMetadata() calls:
new TiffImageParser().getMetadata(bytes, params)

This reproduces the bug, so let's keep digging.

TiffImageParser.getMetadata() starts with:
        FormatCompliance formatCompliance = FormatCompliance.getDefault();
        TiffContents contents = new TiffReader(isStrict(params)).readContents(
                byteSource, params, formatCompliance); <- exception

TiffReader.readContents() starts with:
        Collector collector = new Collector(params);
        read(byteSource, params, formatCompliance, collector); <- exception

TiffReader.read() starts with:
        readDirectories(byteSource, formatCompliance, listener); <- exception

TiffReader.readDirectories() does:
        TiffHeader tiffHeader = readTiffHeader(byteSource, formatCompliance);
        if (!listener.setTiffHeader(tiffHeader))
            return;

        int offset = tiffHeader.offsetToFirstIFD;
        int dirType = TiffDirectory.DIRECTORY_TYPE_ROOT;

        List visited = new ArrayList();
        readDirectory(byteSource, offset, dirType, formatCompliance, listener,
                visited); <- exception

TiffReader.readDirectory() does:
        boolean ignoreNextDirectory = false;
        return readDirectory(byteSource, offset, dirType, formatCompliance,
                listener, ignoreNextDirectory, visited); <- exception

which leaves the top 3 stack frames in the original exception:
    at 
org.apache.sanselan.common.byteSources.ByteSourceArray.getBlock(ByteSourceArray.java:48)
    at 
org.apache.sanselan.formats.tiff.TiffField.fillInValue(TiffField.java:309)
    at 
org.apache.sanselan.formats.tiff.TiffReader.readDirectory(TiffReader.java:195)

TiffReader.readDirectory() is very long, but calls:
                TiffField field = new TiffField(tag, dirType, type, length,
                        valueOffset, valueOffsetBytes, getByteOrder());
                field.setSortHint(i);
                field.fillInValue(byteSource); <- exception
(when i=12, tag=218, dirType=0, type=0, length=1384099793, 
valueOffset=1435828238, valueOffsetBytes=[14,0,-107,85], getByteOrder() returns 
73=BYTE_ORDER_INTEL)

TiffField.fillInValue() does this:
        if (fieldType.isLocalValue(this))
            return;
        int valueLength = getValueLengthInBytes();
        byte bytes[] = byteSource.getBlock(valueOffset, valueLength); <- 
exception
        setOversizeValue(bytes);
(valueOffset=1435828238, valueLength=1384099793)

Maybe we should just ignore blocks that are out of bounds?

I'm attaching a patch for that.

                
> ArrayIndexOutOfBounds exception throwing when get metadata
> ----------------------------------------------------------
>
>                 Key: SANSELAN-55
>                 URL: https://issues.apache.org/jira/browse/SANSELAN-55
>             Project: Commons Sanselan
>          Issue Type: Bug
>    Affects Versions: 0.94-incubator
>         Environment: Ubuntu 11.04/Liftweb/SBT
>            Reporter: Chka Davaadorj
>             Fix For: 0.94-incubator
>
>         Attachments: stupidpic.jpg
>
>
> This is the executed script: Sanselan.getMetadata(new File(filePath))
> But, this throws following exception:
> Caught and thrown by:
> Message: java.lang.ArrayIndexOutOfBoundsException
>       java.lang.System.arraycopy(Native Method)
>       
> org.apache.sanselan.common.byteSources.ByteSourceArray.getBlock(ByteSourceArray.java:52)
>       
> org.apache.sanselan.formats.tiff.TiffField.fillInValue(TiffField.java:309)
>       
> org.apache.sanselan.formats.tiff.TiffReader.readDirectory(TiffReader.java:195)
>       
> org.apache.sanselan.formats.tiff.TiffReader.readDirectory(TiffReader.java:110)
>       
> org.apache.sanselan.formats.tiff.TiffReader.readDirectories(TiffReader.java:101)
>       org.apache.sanselan.formats.tiff.TiffReader.read(TiffReader.java:448)

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to