fix github issue #955 - tile2bmp bounds failure

Issue reported by argrath:  building with 'address sanitizing'
reported tile2bmp writing out of array bounds after the addition
of the generic object tiles.

'MAGICTILENO' in tile2bmp.c is extremely fragile.  It was already
inaccurate before the generic tiles, but had a big enough value to
handle the final row of tiles prior to that.

Fixes #955
This commit is contained in:
PatR
2023-01-12 03:12:56 -08:00
parent 9bf6d837ad
commit a7756a1327
4 changed files with 28 additions and 8 deletions

View File

@@ -1,3 +1,8 @@
# monsters.txt - tile defintions for monsters
# Note: if the number of monster tiles, object tiles, or other tiles
# changes, 'MAGICTILENO' in tile2bmp.c needs to be updated to match!
# Note too: lines beginning with '# tile ' are not comments; other
# lines beginning with '#' are.
. = (71, 108, 108)
A = (0, 0, 0)
B = (0, 182, 255)

View File

@@ -1,3 +1,8 @@
# objects.txt - tile defintions for objects
# Note: if the number of monster tiles, object tiles, or other tiles
# changes, 'MAGICTILENO' in tile2bmp.c needs to be updated to match!
# Note too: lines beginning with '# tile ' are not comments; other
# lines beginning with '#' are.
. = (71, 108, 108)
A = (0, 0, 0)
B = (0, 182, 255)

View File

@@ -1,3 +1,8 @@
# other.txt - tile defintions for 'other' (walls, furniture, explosions)
# Note: if the number of monster tiles, object tiles, or other tiles
# changes, 'MAGICTILENO' in tile2bmp.c needs to be updated to match!
# Note too: lines beginning with '# tile ' are not comments; other
# lines beginning with '#' are.
. = (71, 108, 108)
A = (0, 0, 0)
B = (0, 182, 255)

View File

@@ -56,7 +56,7 @@ extern char *tilename(int, int);
/* The numbers in the following calculation are the
count of tiles present in:
monsters.txt objects.txt other.txt monsters.txt */
#define MAGICTILENO (788 + 459 + 237 + 788)
#define MAGICTILENO (789 + 477 + 240 + 789)
#if BITCOUNT == 4
#define MAX_X 320 /* 2 per byte, 4 bits per pixel */
@@ -230,7 +230,7 @@ main(int argc, char *argv[])
exit(1);
}
while (pass < 4) {
filenum = pass % (sizeof(tilefiles) / sizeof(char *));
filenum = pass % (sizeof tilefiles / sizeof (char *));
if (!fopen_text_file(tilefiles[filenum], RDTMODE)) {
Fprintf(stderr, "usage: tile2bmp (from the util directory)\n");
exit(EXIT_FAILURE);
@@ -260,6 +260,11 @@ main(int argc, char *argv[])
set_grayscale(pass == 3);
/* printf("Colormap initialized\n"); */
while (read_text_tile(tilepixels)) {
if (tilecount >= MAGICTILENO) {
Fprintf(stderr, "tile2bmp: more than %d tiles!\n",
MAGICTILENO);
exit(EXIT_FAILURE);
}
build_bmptile(tilepixels);
tilecount++;
#if BITCOUNT == 4
@@ -275,7 +280,7 @@ main(int argc, char *argv[])
(void) fclose_text_file();
++pass;
}
fwrite(&bmp, sizeof(bmp), 1, fp);
fwrite(&bmp, sizeof bmp, 1, fp);
fclose(fp);
Fprintf(stderr, "Total of %d tiles written to %s.\n", tilecount, bmpname);
@@ -363,14 +368,15 @@ build_bmptile(pixel(*pixels)[TILE_X])
break;
}
if (cur_color >= num_colors)
Fprintf(stderr, "color not in colormap!\n");
Fprintf(stderr, "color not in colormap! (tile #%d)\n",
tilecount);
y = (MAX_Y - 1) - (cur_y + yoffset);
apply_color = cur_color;
#if BITCOUNT == 4
x = (cur_x / 2) + xoffset;
bmp.packtile[y][x] = cur_x % 2
? (uchar)(bmp.packtile[y][x] | cur_color)
: (uchar)(cur_color << 4);
bmp.packtile[y][x] = (cur_x % 2 != 0)
? (uchar) (bmp.packtile[y][x] | cur_color)
: (uchar) (cur_color << 4);
#else
x = cur_x + xoffset;
bmp.packtile[y][x] = (uchar) apply_color;
@@ -380,4 +386,3 @@ build_bmptile(pixel(*pixels)[TILE_X])
}
/*tile2bmp.c*/