7058602: BMP parser bugs found via zzuf fuzzing

Reviewed-by: prr, vadim
This commit is contained in:
Andrew Brygin 2013-10-14 15:32:29 +04:00
parent ccd23da6c7
commit 89b5a10c5f
3 changed files with 95 additions and 24 deletions

View File

@ -187,15 +187,24 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
return 1;
}
@Override
public int getWidth(int imageIndex) throws IOException {
checkIndex(imageIndex);
readHeader();
try {
readHeader();
} catch (IllegalArgumentException e) {
throw new IIOException(I18N.getString("BMPImageReader6"), e);
}
return width;
}
public int getHeight(int imageIndex) throws IOException {
checkIndex(imageIndex);
readHeader();
try {
readHeader();
} catch (IllegalArgumentException e) {
throw new IIOException(I18N.getString("BMPImageReader6"), e);
}
return height;
}
@ -205,7 +214,18 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
}
}
public void readHeader() throws IOException {
/**
* Process the image header.
*
* @exception IllegalStateException if source stream is not set.
*
* @exception IOException if image stream is corrupted.
*
* @exception IllegalArgumentException if the image stream does not contain
* a BMP image, or if a sample model instance to describe the
* image can not be created.
*/
protected void readHeader() throws IOException, IllegalArgumentException {
if (gotHeader)
return;
@ -307,6 +327,9 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
case BI_RLE4: // 4-bit RLE compression
// Read in the palette
if (bitmapOffset < (size + 14)) {
throw new IIOException(I18N.getString("BMPImageReader7"));
}
int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
int sizeOfPalette = numberOfEntries * 4;
palette = new byte[sizeOfPalette];
@ -375,7 +398,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
break;
default:
throw new
RuntimeException(I18N.getString("BMPImageReader2"));
IIOException(I18N.getString("BMPImageReader2"));
}
} else if (size == 108 || size == 124) {
// Windows 4.x BMP
@ -478,7 +501,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
}
} else {
throw new
RuntimeException(I18N.getString("BMPImageReader3"));
IIOException(I18N.getString("BMPImageReader3"));
}
}
@ -660,7 +683,11 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
public Iterator getImageTypes(int imageIndex)
throws IOException {
checkIndex(imageIndex);
readHeader();
try {
readHeader();
} catch (IllegalArgumentException e) {
throw new IIOException(I18N.getString("BMPImageReader6"), e);
}
ArrayList list = new ArrayList(1);
list.add(new ImageTypeSpecifier(originalColorModel,
originalSampleModel));
@ -675,7 +702,11 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
throws IOException {
checkIndex(imageIndex);
if (metadata == null) {
readHeader();
try {
readHeader();
} catch (IllegalArgumentException e) {
throw new IIOException(I18N.getString("BMPImageReader6"), e);
}
}
return metadata;
}
@ -686,7 +717,11 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
public boolean isRandomAccessEasy(int imageIndex) throws IOException {
checkIndex(imageIndex);
readHeader();
try {
readHeader();
} catch (IllegalArgumentException e) {
throw new IIOException(I18N.getString("BMPImageReader6"), e);
}
return metadata.compression == BI_RGB;
}
@ -705,7 +740,11 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
param = getDefaultReadParam();
//read header
readHeader();
try {
readHeader();
} catch (IllegalArgumentException e) {
throw new IIOException(I18N.getString("BMPImageReader6"), e);
}
sourceRegion = new Rectangle(0, 0, 0, 0);
destinationRegion = new Rectangle(0, 0, 0, 0);
@ -817,7 +856,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
default:
throw new
RuntimeException(I18N.getString("BMPImageReader1"));
IIOException(I18N.getString("BMPImageReader1"));
}
break;
@ -833,7 +872,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
default:
throw new
RuntimeException(I18N.getString("BMPImageReader1"));
IIOException(I18N.getString("BMPImageReader1"));
}
break;
@ -874,7 +913,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
default:
throw new
RuntimeException(I18N.getString("BMPImageReader1"));
IIOException(I18N.getString("BMPImageReader1"));
}
case VERSION_4_8_BIT:
@ -890,7 +929,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
default:
throw new
RuntimeException(I18N.getString("BMPImageReader1"));
IIOException(I18N.getString("BMPImageReader1"));
}
break;

View File

@ -21,6 +21,8 @@ BMPImageReader2=Invalid compression specified in BMP stream.
BMPImageReader3=New BMP version not implemented yet.
BMPImageReader4=No ImageIO-style reader is found for
BMPImageReader5=Input has not been set.
BMPImageReader6=Unable to read the image header.
BMPImageReader7=Invalid bitmap offset.
BMPImageWriter0=Output is not an ImageOutputStream.
BMPImageWriter1=The image region to be encoded is empty.
BMPImageWriter2=Only 1 or 3 band image is encoded.
@ -34,7 +36,7 @@ BMPMetadata0=The provided metadata format isn't recognized.
BMPMetadata1=Metadata is read-only.
# WBMP plugin properties
# WBMP plugin properties
WBMPImageReader0=Only one image exists in the stream.
WBMPImageReader1=Input has not been set.
WBMPImageReader2=Bad WBMP header.

View File

@ -167,6 +167,7 @@ public class ComponentSampleModel extends SampleModel
for (int i=0; i<numBands; i++) {
bankIndices[i] = 0;
}
verify();
}
@ -244,24 +245,53 @@ public class ComponentSampleModel extends SampleModel
throw new IllegalArgumentException("Length of bandOffsets must "+
"equal length of bankIndices.");
}
verify();
}
private void verify() {
int requiredSize = getBufferSize();
}
/**
* Returns the size of the data buffer (in data elements) needed
* for a data buffer that matches this ComponentSampleModel.
*/
private long getBufferSize() {
private int getBufferSize() {
int maxBandOff=bandOffsets[0];
for (int i=1; i<bandOffsets.length; i++)
for (int i=1; i<bandOffsets.length; i++) {
maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
}
if (maxBandOff < 0 || maxBandOff > (Integer.MAX_VALUE - 1)) {
throw new IllegalArgumentException("Invalid band offset");
}
if (pixelStride < 0 || pixelStride > (Integer.MAX_VALUE / width)) {
throw new IllegalArgumentException("Invalid pixel stride");
}
if (scanlineStride < 0 || scanlineStride > (Integer.MAX_VALUE / height)) {
throw new IllegalArgumentException("Invalid scanline stride");
}
int size = maxBandOff + 1;
int val = pixelStride * (width - 1);
if (val > (Integer.MAX_VALUE - size)) {
throw new IllegalArgumentException("Invalid pixel stride");
}
size += val;
val = scanlineStride * (height - 1);
if (val > (Integer.MAX_VALUE - size)) {
throw new IllegalArgumentException("Invalid scan stride");
}
size += val;
long size = 0;
if (maxBandOff >= 0)
size += maxBandOff+1;
if (pixelStride > 0)
size += pixelStride * (width-1);
if (scanlineStride > 0)
size += scanlineStride*(height-1);
return size;
}
@ -409,7 +439,7 @@ public class ComponentSampleModel extends SampleModel
public DataBuffer createDataBuffer() {
DataBuffer dataBuffer = null;
int size = (int)getBufferSize();
int size = getBufferSize();
switch (dataType) {
case DataBuffer.TYPE_BYTE:
dataBuffer = new DataBufferByte(size, numBanks);