Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ The <action> type attribute can be add,update,fix,remove.
<action type="fix" dev="ggregory" due-to="alhuda, Gary Gregory">Fix int overflow in PCX image buffer sizing, now throws AllocationRequestException (#552).</action>
<action type="fix" dev="ggregory" due-to="alhuda, Gary Gregory">Fix int overflow in Allocator.array/arrayList size checks (#551).</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">Add messages when throwing NullPointerException.</action>
<action type="fix" due-to="Sharang Gupta">Fix int overflow in the JPEG raster allocation guard, now throws AllocationRequestException (#570).</action>
<!-- ADD -->
<action type="fix" dev="ggregory" due-to="Sean R, Gary Gregory">Add unit tests (#553).</action>
<!-- UPDATE -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,8 @@ public void visitSos(final int marker, final byte[] markerBytes, final byte[] im
final int[] preds = Allocator.intArray(sofnSegment.numberOfComponents);
final ColorModel colorModel;
final WritableRaster raster;
Allocator.check(Integer.BYTES * sofnSegment.width * sofnSegment.height);
// Compute the request in long so a large width times height cannot overflow int and slip past the guard.
Allocator.check((long) sofnSegment.width * sofnSegment.height, Integer.BYTES);
switch (sofnSegment.numberOfComponents) {
case 4:
// Special handling for the application-RGB case: TIFF files with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@

package org.apache.commons.imaging.formats.jpeg.decoder;

import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.io.File;

import org.apache.commons.imaging.ImagingException;
import org.apache.commons.imaging.bytesource.ByteSource;
import org.apache.commons.imaging.common.AllocationRequestException;
import org.apache.commons.imaging.test.TestResources;
import org.junit.jupiter.api.Test;

Expand All @@ -41,4 +43,24 @@ void testDecodeBadFile() {
final ByteSource byteSourceFile = ByteSource.file(inputFile);
assertThrows(ImagingException.class, () -> new JpegDecoder().decode(byteSourceFile));
}

/**
* A SOF whose width times height, scaled by {@link Integer#BYTES}, overflows a 32-bit int must not slip past the raster allocation guard (IMAGING-379).
* Here 0x8000 by 0x8000 makes {@code Integer.BYTES * width * height} wrap to zero; the request is now computed in long and still rejected.
*/
@Test
void testOversizedRasterAllocationIsRejected() {
final byte[] jpeg = {
(byte) 0xFF, (byte) 0xD8, // SOI
(byte) 0xFF, (byte) 0xC0, 0x00, 0x0B, // SOF0, segment length 11
0x08, (byte) 0x80, 0x00, (byte) 0x80, 0x00, // precision 8, height 0x8000, width 0x8000
0x01, 0x01, 0x11, 0x00, // one component: id 1, sampling 0x11, quantization table 0
(byte) 0xFF, (byte) 0xDA, 0x00, 0x08, // SOS, segment length 8
0x01, 0x01, 0x00, 0x00, 0x3F, 0x00, // one component: selector 1, tables 0; Ss 0, Se 63, Ah/Al 0
0x00, 0x00, // minimal entropy payload
(byte) 0xFF, (byte) 0xD9, // EOI
};
final ImagingException ex = assertThrows(ImagingException.class, () -> new JpegDecoder().decode(ByteSource.array(jpeg)));
assertInstanceOf(AllocationRequestException.class, ex.getCause());
}
}