mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-03 03:25:28 -04:00
#330 Now guards against buffer overruns in RLE decoder.
This commit is contained in:
parent
31cb79d2b9
commit
a84cc1c060
@ -216,50 +216,55 @@ public final class BMPImageReader extends ImageReaderBase {
|
|||||||
throw new IIOException("Multiple planes not supported");
|
throw new IIOException("Multiple planes not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (header.getBitCount()) {
|
try {
|
||||||
case 1:
|
switch (header.getBitCount()) {
|
||||||
case 2:
|
case 1:
|
||||||
case 4:
|
case 2:
|
||||||
case 8:
|
case 4:
|
||||||
return ImageTypeSpecifiers.createFromIndexColorModel(readColorMap());
|
case 8:
|
||||||
|
return ImageTypeSpecifiers.createFromIndexColorModel(readColorMap());
|
||||||
|
|
||||||
case 16:
|
case 16:
|
||||||
if (header.hasMasks()) {
|
if (header.hasMasks()) {
|
||||||
return ImageTypeSpecifiers.createPacked(
|
return ImageTypeSpecifiers.createPacked(
|
||||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||||
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
|
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
|
||||||
DataBuffer.TYPE_USHORT, false
|
DataBuffer.TYPE_USHORT, false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default if no mask is 555
|
// Default if no mask is 555
|
||||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_555_RGB);
|
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_555_RGB);
|
||||||
|
|
||||||
case 24:
|
case 24:
|
||||||
if (header.getCompression() != DIB.COMPRESSION_RGB) {
|
if (header.getCompression() != DIB.COMPRESSION_RGB) {
|
||||||
throw new IIOException("Unsupported compression for RGB: " + header.getCompression());
|
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:
|
case 32:
|
||||||
if (header.hasMasks()) {
|
if (header.hasMasks()) {
|
||||||
return ImageTypeSpecifiers.createPacked(
|
return ImageTypeSpecifiers.createPacked(
|
||||||
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||||
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
|
header.masks[0], header.masks[1], header.masks[2], header.masks[3],
|
||||||
DataBuffer.TYPE_INT, false
|
DataBuffer.TYPE_INT, false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default if no mask
|
// Default if no mask
|
||||||
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
|
return ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
if (header.getCompression() == DIB.COMPRESSION_JPEG || header.getCompression() == DIB.COMPRESSION_PNG) {
|
if (header.getCompression() == DIB.COMPRESSION_JPEG || header.getCompression() == DIB.COMPRESSION_PNG) {
|
||||||
return initReaderDelegate(header.getCompression()).getRawImageType(0);
|
return initReaderDelegate(header.getCompression()).getRawImageType(0);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new IIOException("Unsupported bit count: " + header.getBitCount());
|
throw new IIOException("Unsupported bit count: " + header.getBitCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
throw new IIOException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ import java.util.Arrays;
|
|||||||
* @version $Id: RLE4Decoder.java#1 $
|
* @version $Id: RLE4Decoder.java#1 $
|
||||||
*/
|
*/
|
||||||
final class RLE4Decoder extends AbstractRLEDecoder {
|
final class RLE4Decoder extends AbstractRLEDecoder {
|
||||||
final static int BIT_MASKS[] = {0xf0, 0x0f};
|
final static int[] BIT_MASKS = {0xf0, 0x0f};
|
||||||
final static int BIT_SHIFTS[] = {4, 0};
|
final static int[] BIT_SHIFTS = {4, 0};
|
||||||
|
|
||||||
public RLE4Decoder(final int width) {
|
public RLE4Decoder(final int width) {
|
||||||
super(width, 4);
|
super(width, 4);
|
||||||
@ -94,7 +94,7 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
|||||||
boolean paddingByte = (((byte2 + 1) / 2) % 2) != 0;
|
boolean paddingByte = (((byte2 + 1) / 2) % 2) != 0;
|
||||||
|
|
||||||
int packed = 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) {
|
if (i % 2 == 0) {
|
||||||
packed = checkEOF(stream.read());
|
packed = checkEOF(stream.read());
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ final class RLE4Decoder extends AbstractRLEDecoder {
|
|||||||
else {
|
else {
|
||||||
// Encoded mode
|
// Encoded mode
|
||||||
// Replicate the two samples in byte2 as many times as byte1 says
|
// 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]);
|
row[srcX / 2] |= (byte) (((byte2 & BIT_MASKS[i % 2]) >> BIT_SHIFTS[i % 2]) << BIT_SHIFTS[srcX % 2]);
|
||||||
srcX++;
|
srcX++;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ final class RLE8Decoder extends AbstractRLEDecoder {
|
|||||||
// an additional padding byte is in the stream and must be skipped
|
// an additional padding byte is in the stream and must be skipped
|
||||||
boolean paddingByte = (byte2 % 2) != 0;
|
boolean paddingByte = (byte2 % 2) != 0;
|
||||||
|
|
||||||
while (byte2-- > 0) {
|
while (byte2-- > 0 && srcX < row.length) {
|
||||||
row[srcX++] = (byte) checkEOF(stream.read());
|
row[srcX++] = (byte) checkEOF(stream.read());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ final class RLE8Decoder extends AbstractRLEDecoder {
|
|||||||
// Encoded mode
|
// Encoded mode
|
||||||
// Replicate byte2 as many times as byte1 says
|
// Replicate byte2 as many times as byte1 says
|
||||||
byte value = (byte) byte2;
|
byte value = (byte) byte2;
|
||||||
while (byte1-- > 0) {
|
while (byte1-- > 0 && srcX < row.length) {
|
||||||
row[srcX++] = value;
|
row[srcX++] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user