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)