#330 Now guards against buffer overruns in RLE decoder.

This commit is contained in:
Harald Kuhr 2020-11-17 22:33:50 +01:00
parent 31cb79d2b9
commit a84cc1c060
3 changed files with 48 additions and 43 deletions

View File

@ -216,50 +216,55 @@ public final class BMPImageReader extends ImageReaderBase {
throw new IIOException("Multiple planes not supported");
}
switch (header.getBitCount()) {
case 1:
case 2:
case 4:
case 8:
return ImageTypeSpecifiers.createFromIndexColorModel(readColorMap());
try {
switch (header.getBitCount()) {
case 1:
case 2:
case 4:
case 8:
return ImageTypeSpecifiers.createFromIndexColorModel(readColorMap());
case 16:
if (header.hasMasks()) {
return ImageTypeSpecifiers.createPacked(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
DataBuffer.TYPE_USHORT, false
);
}
case 16:
if (header.hasMasks()) {
return ImageTypeSpecifiers.createPacked(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
DataBuffer.TYPE_USHORT, false
);
}
// Default if no mask is 555
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_555_RGB);
// Default if no mask is 555
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_555_RGB);
case 24:
if (header.getCompression() != DIB.COMPRESSION_RGB) {
throw new IIOException("Unsupported compression for RGB: " + header.getCompression());
}
case 24:
if (header.getCompression() != DIB.COMPRESSION_RGB) {
throw new IIOException("Unsupported compression for RGB: " + header.getCompression());
}
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_3BYTE_BGR);
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_3BYTE_BGR);
case 32:
if (header.hasMasks()) {
return ImageTypeSpecifiers.createPacked(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
DataBuffer.TYPE_INT, false
);
}
case 32:
if (header.hasMasks()) {
return ImageTypeSpecifiers.createPacked(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
DataBuffer.TYPE_INT, false
);
}
// Default if no mask
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
// Default if no mask
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
case 0:
if (header.getCompression() == DIB.COMPRESSION_JPEG || header.getCompression() == DIB.COMPRESSION_PNG) {
return initReaderDelegate(header.getCompression()).getRawImageType(0);
}
default:
throw new IIOException("Unsupported bit count: " + header.getBitCount());
case 0:
if (header.getCompression() == DIB.COMPRESSION_JPEG || header.getCompression() == DIB.COMPRESSION_PNG) {
return initReaderDelegate(header.getCompression()).getRawImageType(0);
}
default:
throw new IIOException("Unsupported bit count: " + header.getBitCount());
}
}
catch (IllegalArgumentException e) {
throw new IIOException(e.getMessage(), e);
}
}

View File

@ -41,8 +41,8 @@ import java.util.Arrays;
* @version $Id: RLE4Decoder.java#1 $
*/
final class RLE4Decoder extends AbstractRLEDecoder {
final static int BIT_MASKS[] = {0xf0, 0x0f};
final static int BIT_SHIFTS[] = {4, 0};
final static int[] BIT_MASKS = {0xf0, 0x0f};
final static int[] BIT_SHIFTS = {4, 0};
public RLE4Decoder(final int width) {
super(width, 4);
@ -94,7 +94,7 @@ final class RLE4Decoder extends AbstractRLEDecoder {
boolean paddingByte = (((byte2 + 1) / 2) % 2) != 0;
int packed = 0;
for (int i = 0; i < byte2; i++) {
for (int i = 0; i < byte2 && srcX / 2 < row.length; i++) {
if (i % 2 == 0) {
packed = checkEOF(stream.read());
}
@ -111,7 +111,7 @@ final class RLE4Decoder extends AbstractRLEDecoder {
else {
// Encoded mode
// Replicate the two samples in byte2 as many times as byte1 says
for (int i = 0; i < byte1; i++) {
for (int i = 0; i < byte1 && srcX / 2 < row.length; i++) {
row[srcX / 2] |= (byte) (((byte2 & BIT_MASKS[i % 2]) >> BIT_SHIFTS[i % 2]) << BIT_SHIFTS[srcX % 2]);
srcX++;
}

View File

@ -94,7 +94,7 @@ final class RLE8Decoder extends AbstractRLEDecoder {
// an additional padding byte is in the stream and must be skipped
boolean paddingByte = (byte2 % 2) != 0;
while (byte2-- > 0) {
while (byte2-- > 0 && srcX < row.length) {
row[srcX++] = (byte) checkEOF(stream.read());
}
@ -107,7 +107,7 @@ final class RLE8Decoder extends AbstractRLEDecoder {
// Encoded mode
// Replicate byte2 as many times as byte1 says
byte value = (byte) byte2;
while (byte1-- > 0) {
while (byte1-- > 0 && srcX < row.length) {
row[srcX++] = value;
}
}