Tim Scheckenbach created IMAGING-387:
----------------------------------------

             Summary: Imaging.getBufferedImage throws 
NegativeArraySizeException because DataReaderStrips truncates a huge Deflate 
strip length to a negative int and Allocator does not reject it
                 Key: IMAGING-387
                 URL: https://issues.apache.org/jira/browse/IMAGING-387
             Project: Commons Imaging
          Issue Type: Bug
          Components: Format: TIFF
    Affects Versions: 1.0.0-alpha6
            Reporter: Tim Scheckenbach
         Attachments: crash-1e586fbafbe3ae55f53ef012d2ddcf02ff8d6609

Calling
{code:java}
Imaging.getBufferedImage(new 
File("crash-1e586fbafbe3ae55f53ef012d2ddcf02ff8d6609"));
{code}
on the attached 898-byte TIFF results in:
{code}
java.lang.NegativeArraySizeException: -1070635447
        at 
org.apache.commons.imaging.common.Allocator.byteArray(Allocator.java:92)
        at 
org.apache.commons.imaging.common.ZlibDeflate.decompress(ZlibDeflate.java:69)
        at 
org.apache.commons.imaging.formats.tiff.datareaders.AbstractImageDataReader.decompress(AbstractImageDataReader.java:313)
        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: ImageWidth 16777798, ImageLength 13825, 
SamplesPerPixel 1, PhotometricInterpretation WhiteIsZero, Compression 8 (Adobe 
Deflate). That is a 1-bit bilevel image whose uncompressed strip is far larger 
than {{Integer.MAX_VALUE}}.

{{DataReaderStrips.readImageData}} computes the decompressed strip size as a 
{{long}}, then narrows it:

{code:java}
final long bytesPerRow = (bitsPerPixel * width + 7) / 8;
final long bytesPerStrip = rowsInThisStrip * bytesPerRow;
final byte[] decompressed = decompress(compressed, compression, (int) 
bytesPerStrip, width, (int) rowsInThisStrip);
{code}

{{13825 * ((1 * 16777798 + 7) / 8)}} is {{28994135625}}. The {{(int)}} cast 
wraps that to {{-1070635447}}.

{{AbstractImageDataReader.decompress}} then calls 
{{ZlibDeflate.decompress(bytes, expectedSize)}}, which does 
{{Allocator.byteArray(expectedSize)}}. {{Allocator.check}} only rejects 
{{request > LIMIT}} (1 GB). A negative request is smaller than the limit, so it 
is returned unchanged and {{new byte[negative]}} throws 
{{NegativeArraySizeException}}.

{{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