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)