Skip to content

Commit

Permalink
Rearranged BMP reader to prevent incorrectly decoded images
Browse files Browse the repository at this point in the history
  • Loading branch information
Argent77 committed Jan 24, 2015
1 parent b67d335 commit a6cc6a5
Showing 1 changed file with 45 additions and 44 deletions.
89 changes: 45 additions & 44 deletions src/infinity/resource/graphics/BmpResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,51 +37,52 @@ public final class BmpResource implements Resource, ActionListener
public BmpResource(ResourceEntry entry) throws Exception
{
this.entry = entry;
try {
image = ImageIO.read(entry.getResourceDataAsStream());
} catch (Exception e) {
image = null;
byte[] data = entry.getResourceData();
// Checking signature
if (!"BM".equals(new String(data, 0, 2))) {
throw new Exception("Invalid BMP resource");
}
if (image == null) {
byte[] data = entry.getResourceData();
new String(data, 0, 2); // Signature
DynamicArray.getInt(data, 2); // Size
DynamicArray.getInt(data, 6); // Reserved
int rasteroff = DynamicArray.getInt(data, 10);

DynamicArray.getInt(data, 14); // Headersize
int width = DynamicArray.getInt(data, 18);
int height = DynamicArray.getInt(data, 22);
DynamicArray.getShort(data, 26); // Planes
int bitcount = (int)DynamicArray.getShort(data, 28);
int compression = DynamicArray.getInt(data, 30);
if ((compression == 0 || compression == 3) && bitcount <= 32) {
DynamicArray.getInt(data, 34); // Comprsize
DynamicArray.getInt(data, 38); // Xpixprm
DynamicArray.getInt(data, 42); // Ypixprm
int colsUsed = DynamicArray.getInt(data, 46); // Colorsused
DynamicArray.getInt(data, 50); // Colorsimp

if (bitcount <= 8) {
if (colsUsed == 0)
colsUsed = 1 << bitcount;
int palSize = 4 * colsUsed;
palette = new Palette(data, rasteroff - palSize, palSize);
}

int bytesprline = bitcount * width / 8;
int padded = 4 - bytesprline % 4;
if (padded == 4)
padded = 0;

image = ColorConvert.createCompatibleImage(width, height, bitcount >= 32);
int offset = rasteroff;
for (int y = height - 1; y >= 0; y--) {
setPixels(data, offset, bitcount, bytesprline, y, palette);
offset += bytesprline + padded;
}
} else {
throw new Exception(String.format("%1$s: Unsupported BMP format", entry.getResourceName()));
DynamicArray.getInt(data, 2); // Size
DynamicArray.getInt(data, 6); // Reserved
int rasteroff = DynamicArray.getInt(data, 10);

DynamicArray.getInt(data, 14); // Headersize
int width = DynamicArray.getInt(data, 18);
int height = DynamicArray.getInt(data, 22);
DynamicArray.getShort(data, 26); // Planes
int bitcount = (int)DynamicArray.getShort(data, 28);
int compression = DynamicArray.getInt(data, 30);
if ((compression == 0 || compression == 3) && bitcount <= 32) {
DynamicArray.getInt(data, 34); // Comprsize
DynamicArray.getInt(data, 38); // Xpixprm
DynamicArray.getInt(data, 42); // Ypixprm
int colsUsed = DynamicArray.getInt(data, 46); // Colorsused
DynamicArray.getInt(data, 50); // Colorsimp

if (bitcount <= 8) {
if (colsUsed == 0)
colsUsed = 1 << bitcount;
int palSize = 4 * colsUsed;
palette = new Palette(data, rasteroff - palSize, palSize);
}

int bytesprline = bitcount * width / 8;
int padded = 4 - bytesprline % 4;
if (padded == 4)
padded = 0;

image = ColorConvert.createCompatibleImage(width, height, bitcount >= 32);
int offset = rasteroff;
for (int y = height - 1; y >= 0; y--) {
setPixels(data, offset, bitcount, bytesprline, y, palette);
offset += bytesprline + padded;
}
} else {
try {
image = ImageIO.read(entry.getResourceDataAsStream());
} catch (Exception e) {
image = null;
throw new Exception("Unsupported BMP format");
}
}
}
Expand Down

0 comments on commit a6cc6a5

Please sign in to comment.