summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2015-11-20 03:00:11 +0000
committerJohn-Mark Bell <jmb@netsurf-browser.org>2015-11-20 14:14:09 +0000
commit041df43bbe273b0829132b0b17d89a69da2927d4 (patch)
treeac339fbd470826b7459141b2af2900c0ca3e2224
parent49427b52ba41a1813e3822301612e2e170107efd (diff)
downloadlibnsbmp-041df43bbe273b0829132b0b17d89a69da2927d4.tar.gz
libnsbmp-041df43bbe273b0829132b0b17d89a69da2927d4.tar.bz2
Range check colour table accesses.
Issue-reported-by: Hans Jerry Illikainen
-rw-r--r--src/libnsbmp.c31
-rw-r--r--test/bmpsuite/coloob.bmpbin0 -> 126 bytes
2 files changed, 26 insertions, 5 deletions
diff --git a/src/libnsbmp.c b/src/libnsbmp.c
index 64aed18..123ed9e 100644
--- a/src/libnsbmp.c
+++ b/src/libnsbmp.c
@@ -865,8 +865,12 @@ static bmp_result bmp_decode_rgb(bmp_image *bmp, uint8_t **start, int bytes) {
bmp->decoded = true;
/* Determine transparent index */
- if (bmp->limited_trans)
- bmp->transparent_index = bmp->colour_table[(*data >> bit_shifts[0]) & bit_mask];
+ if (bmp->limited_trans) {
+ uint32_t idx = (*data >> bit_shifts[0]) & bit_mask;
+ if (idx >= bmp->colours)
+ return BMP_DATA_ERROR;
+ bmp->transparent_index = bmp->colour_table[idx];
+ }
for (y = 0; y < bmp->height; y++) {
while (addr != (((intptr_t)data) & 3))
@@ -879,11 +883,15 @@ static bmp_result bmp_decode_rgb(bmp_image *bmp, uint8_t **start, int bytes) {
else
scanline = (void *)(bottom - (y * swidth));
for (x = 0; x < bmp->width; x++) {
+ uint32_t idx;
if (bit >= ppb) {
bit = 0;
cur_byte = *data++;
}
- scanline[x] = bmp->colour_table[(cur_byte >> bit_shifts[bit++]) & bit_mask];
+ idx = (cur_byte >> bit_shifts[bit++]) & bit_mask;
+ if (idx >= bmp->colours)
+ return BMP_DATA_ERROR;
+ scanline[x] = bmp->colour_table[idx];
if ((bmp->limited_trans) && (scanline[x] == bmp->transparent_index))
scanline[x] = bmp->trans_colour;
}
@@ -1014,13 +1022,16 @@ static bmp_result bmp_decode_rle(bmp_image *bmp, uint8_t *data, int bytes, int s
* routines if so */
if (size == 8) {
for (i = 0; i < length; i++) {
+ uint32_t idx = (uint32_t) *data++;
if (x >= bmp->width) {
x = 0;
if (++y > bmp->height)
return BMP_DATA_ERROR;
scanline -= bmp->width;
}
- scanline[x++] = bmp->colour_table[(int)*data++];
+ if (idx >= bmp->colours)
+ return BMP_DATA_ERROR;
+ scanline[x++] = bmp->colour_table[idx];
}
} else {
for (i = 0; i < length; i++) {
@@ -1032,9 +1043,13 @@ static bmp_result bmp_decode_rle(bmp_image *bmp, uint8_t *data, int bytes, int s
}
if ((i & 1) == 0) {
pixel = *data++;
+ if ((pixel >> 4) >= bmp->colours)
+ return BMP_DATA_ERROR;
scanline[x++] = bmp->colour_table
[pixel >> 4];
} else {
+ if ((pixel & 0xf) >= bmp->colours)
+ return BMP_DATA_ERROR;
scanline[x++] = bmp->colour_table
[pixel & 0xf];
}
@@ -1065,7 +1080,10 @@ static bmp_result bmp_decode_rle(bmp_image *bmp, uint8_t *data, int bytes, int s
* checking the bounds on entry and using some simply copying
* routines if so */
if (size == 8) {
- pixel = bmp->colour_table[(int)*data++];
+ uint32_t idx = (uint32_t) *data++;
+ if (idx >= bmp->colours)
+ return BMP_DATA_ERROR;
+ pixel = bmp->colour_table[idx];
for (i = 0; i < length; i++) {
if (x >= bmp->width) {
x = 0;
@@ -1077,6 +1095,9 @@ static bmp_result bmp_decode_rle(bmp_image *bmp, uint8_t *data, int bytes, int s
}
} else {
pixel2 = *data++;
+ if ((pixel2 >> 4) >= bmp->colours ||
+ (pixel2 & 0xf) >= bmp->colours)
+ return BMP_DATA_ERROR;
pixel = bmp->colour_table[pixel2 >> 4];
pixel2 = bmp->colour_table[pixel2 & 0xf];
for (i = 0; i < length; i++) {
diff --git a/test/bmpsuite/coloob.bmp b/test/bmpsuite/coloob.bmp
new file mode 100644
index 0000000..49214f7
--- /dev/null
+++ b/test/bmpsuite/coloob.bmp
Binary files differ