Tim Scheckenbach created IMAGING-388:
----------------------------------------

             Summary: Imaging.getBufferedImage causes an 
ArrayIndexOutOfBoundsException in BitParser.getSample on a greyscale PNG whose 
IHDR width overflows the scanline-size multiply
                 Key: IMAGING-388
                 URL: https://issues.apache.org/jira/browse/IMAGING-388
             Project: Commons Imaging
          Issue Type: Bug
          Components: Format: PNG
    Affects Versions: 1.0.0-alpha7
            Reporter: Tim Scheckenbach
         Attachments: crash-273c4eec501fa92b0bd4b7443bc4af901937b3b0

Calling
{code:java}
Imaging.getBufferedImage(new 
File("crash-273c4eec501fa92b0bd4b7443bc4af901937b3b0"));
{code}
on the attached PNG results in:
{code}
java.lang.ArrayIndexOutOfBoundsException: Index 9 out of bounds for length 9
        at 
org.apache.commons.imaging.formats.png.BitParser.getSample(BitParser.java:38)
        at 
org.apache.commons.imaging.formats.png.BitParser.getSampleAsByte(BitParser.java:56)
        at 
org.apache.commons.imaging.formats.png.AbstractScanExpediter.getRgb(AbstractScanExpediter.java:99)
        at 
org.apache.commons.imaging.formats.png.ScanExpediterSimple.drive(ScanExpediterSimple.java:48)
        at 
org.apache.commons.imaging.formats.png.PngImageParser.getBufferedImage(PngImageParser.java:303)
        at 
org.apache.commons.imaging.formats.png.PngImageParser.getBufferedImage(PngImageParser.java:75)
{code}

The image is a 536870921x1 PNG with IHDR colour type 0 (greyscale), bit depth 8 
and no interlace. Bit depth 8 on greyscale is legal, and the greyscale raster 
is about 512 MB, so it sits under Allocator's 1 GB cap and decoding proceeds.

After some investigation: {{ScanExpediterSimple.drive}} sizes each scanline 
with a 32-bit multiply,
{code:java}
final int bitsPerScanLine = bitsPerPixel * width;
final int pixelBytesPerScanLine = getBitsToBytesRoundingUp(bitsPerScanLine);
{code}
{{8 * 536870921 = 4294967368}}, which wraps to {{72}}. {{(72 + 7) / 8 = 9}}, so 
the scanline buffer is 9 bytes. The pixel loop still runs {{x}} from {{0}} to 
{{width - 1}}. At {{x = 9}}, the 8-bit branch of {{BitParser.getSample}} 
({{BitParser.java:38}}) reads {{bytes[9]}} and throws. {{BitParser}} never 
checks that the computed byte index is in range.

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