Tim Scheckenbach created IMAGING-386:
----------------------------------------

             Summary: Imaging.getBufferedImage throws ClassCastException 
because TiffField.getIntValue assumes FillOrder is a Number, but a BYTE field 
with count != 1 is a byte[]
                 Key: IMAGING-386
                 URL: https://issues.apache.org/jira/browse/IMAGING-386
             Project: Commons Imaging
          Issue Type: Bug
          Components: Format: TIFF
    Affects Versions: 1.0.0-alpha6
            Reporter: Tim Scheckenbach
         Attachments: crash-46f4bb78375b6353270d3c220d17d6101f916eab

Calling
{code:java}
Imaging.getBufferedImage(new 
File("crash-46f4bb78375b6353270d3c220d17d6101f916eab"));
{code}
on the attached 438-byte TIFF results in:
{code}
java.lang.ClassCastException: class [B cannot be cast to class java.lang.Number
        at 
org.apache.commons.imaging.formats.tiff.TiffField.getIntValue(TiffField.java:332)
        at 
org.apache.commons.imaging.formats.tiff.datareaders.AbstractImageDataReader.decompress(AbstractImageDataReader.java:248)
        at 
org.apache.commons.imaging.formats.tiff.datareaders.DataReaderStrips.readImageData(DataReaderStrips.java:311)
        at 
org.apache.commons.imaging.formats.tiff.TiffImageParser.getBufferedImage(TiffImageParser.java:386)
        at 
org.apache.commons.imaging.formats.tiff.TiffDirectory.getTiffImage(TiffDirectory.java:1015)
        at 
org.apache.commons.imaging.formats.tiff.TiffImageParser.getBufferedImage(TiffImageParser.java:241)
{code}

The file is a little-endian TIFF whose FillOrder tag (0x010A) is type BYTE with 
count 0. The spec requires a single SHORT (1 = left-to-right, 2 = 
right-to-left).

{{AbstractImageDataReader.decompress}} always reads that tag before any codec 
runs:

{code:java}
final TiffField fillOrderField = 
directory.findField(TiffTagConstants.TIFF_TAG_FILL_ORDER);
int fillOrder = TiffTagConstants.FILL_ORDER_VALUE_NORMAL;
if (fillOrderField != null) {
    fillOrder = fillOrderField.getIntValue();
}
{code}

{{TiffField.getValue}} uses the *actual* field type, not the TagInfo SHORT. 
{{FieldTypeByte.getValue}} returns a boxed {{Byte}} only when {{count == 1}}; 
otherwise it returns {{byte[]}}. Count 0 therefore yields a {{byte[]}}.

{{TiffField.getIntValue}} then does:

{code:java}
final Object o = getValue();
if (o == null) {
    throw new ImagingException("Missing value: " + 
getTagInfo().getDescription());
}
return ((Number) o).intValue();
{code}

{{getIntArrayValue}} / {{getIntValueOrArraySum}} already reject a {{byte[]}} 
with {{ImagingException}}. {{getIntValue}} does not.

{{Imaging.getBufferedImage}} is declared as {{throws ImagingException, 
IOException}}, so callers handling the documented exception types do not catch 
this one.


I have attached the image to the issue.

Found by the CISPA Fandango Team.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to