Fix bitmap overruns when WORLD_X * WORLD_Y not a multiple of 16

World-sized bitmaps were allocated with size WORLD_SZ() / 8, which
expands to (WORLD_X * WORLD_Y / 2) / 8.  The divisions truncate unless
WORLD_X * WORLD_Y is a multiple of 16.  The bitmaps were one byte too
small then.  Bitmap overruns happen when:

* A lookout looks at one of the last sectors of the sector file.
  Besides commands look and llook, this affects navigate and march
  sub-command 'l'.

* Command spy spies into one of the last sectors of the sector file.

* A map or nmap (but not a bmap) shows one of the last sectors of the
  sector file, or a sector that can see one of the last sectors
  (visual range is two sectors at 100% efficiency).  Besides commands
  lmap, map, nmap, pmap, smap, this affects move and transport
  sub-command 'm'.

Diagnosed with valgrind.

Already broken in BSD Empire 1.1 (bitmaps were on the stack then).
This commit is contained in:
Markus Armbruster 2011-02-28 06:58:51 +01:00
parent 6c9363cc4f
commit 88983a1a2e
3 changed files with 7 additions and 7 deletions

View file

@ -70,7 +70,7 @@ do_look(int type)
if (!snxtitem(&ni, type, player->argp[1], NULL))
return RET_SYN;
bitmap = calloc(WORLD_SZ() / 8, 1);
bitmap = calloc((WORLD_SZ() + 7) / 8, 1);
if (!bitmap) {
logerror("malloc failed in do_look\n");
pr("Memory error. Tell the deity.\n");

View file

@ -30,7 +30,7 @@
* Known contributors to this file:
* Dave Pare, 1986
* Steve McClure, 1998-2000
* Markus Armbruster, 2005-2008
* Markus Armbruster, 2005-2011
*/
#include <config.h>
@ -86,7 +86,7 @@ spy(void)
pr("You don't have the BTU's for spying on that scale!\n");
return RET_FAIL;
}
bitmap = calloc(WORLD_SZ() / 8, 1);
bitmap = calloc((WORLD_SZ() + 7) / 8, 1);
if (!bitmap) {
logerror("malloc failed in do_look\n");
pr("Memory error. Tell the deity.\n");

View file

@ -30,7 +30,7 @@
* Known contributors to this file:
* Ken Stevens, 1995
* Steve McClure, 1998
* Markus Armbruster, 2004-2008
* Markus Armbruster, 2004-2011
* Ron Koenderink, 2006
*/
@ -148,7 +148,7 @@ draw_map(int bmap, char origin, int map_flags, struct nstr_sect *nsp)
}
}
if (!bitmap)
bitmap = malloc(WORLD_SZ() / 8);
bitmap = malloc((WORLD_SZ() + 7) / 8);
if (!wmapbuf || !wmap || !bitmap) {
pr("Memory error, tell the deity.\n");
logerror("malloc failed in draw_map\n");
@ -202,7 +202,7 @@ draw_map(int bmap, char origin, int map_flags, struct nstr_sect *nsp)
struct sctstr sect;
if (!player->god) {
memset(bitmap, 0, WORLD_SZ() / 8);
memset(bitmap, 0, (WORLD_SZ() + 7) / 8);
bitinit2(nsp, bitmap, player->cnum);
}
while (nxtsct(nsp, &sect) && !player->aborted) {
@ -221,7 +221,7 @@ draw_map(int bmap, char origin, int map_flags, struct nstr_sect *nsp)
int changed = 0;
if (!player->god) {
memset(bitmap, 0, WORLD_SZ() / 8);
memset(bitmap, 0, (WORLD_SZ() + 7) / 8);
bitinit2(nsp, bitmap, player->cnum);
}
while (nxtsct(nsp, &sect) && !player->aborted) {