]> git.pond.sub.org Git - empserver/commitdiff
Fix bitmap overruns when WORLD_X * WORLD_Y not a multiple of 16
authorMarkus Armbruster <armbru@pond.sub.org>
Mon, 28 Feb 2011 05:58:51 +0000 (06:58 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Mon, 11 Apr 2011 20:29:12 +0000 (22:29 +0200)
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).

src/lib/commands/look.c
src/lib/commands/spy.c
src/lib/subs/maps.c

index 493d7826c674b33d4380f9d2125b4970277038b2..fffd99b5d339af8a400be83d7feb23073f242137 100644 (file)
@@ -70,7 +70,7 @@ do_look(int type)
 
     if (!snxtitem(&ni, type, player->argp[1], NULL))
        return RET_SYN;
 
     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");
     if (!bitmap) {
        logerror("malloc failed in do_look\n");
        pr("Memory error.  Tell the deity.\n");
index 729186061f37abe2b8a3131d32261c213ffc7e14..b746b3d67a7fdf1cfbe52e0742527629b02dc74a 100644 (file)
@@ -30,7 +30,7 @@
  *  Known contributors to this file:
  *     Dave Pare, 1986
  *     Steve McClure, 1998-2000
  *  Known contributors to this file:
  *     Dave Pare, 1986
  *     Steve McClure, 1998-2000
- *     Markus Armbruster, 2005-2008
+ *     Markus Armbruster, 2005-2011
  */
 
 #include <config.h>
  */
 
 #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;
     }
        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");
     if (!bitmap) {
        logerror("malloc failed in do_look\n");
        pr("Memory error.  Tell the deity.\n");
index e2c4d890061c2be93765e95eebc825efc7c5ee8d..14e894642868af34d01819d904a46055634e09e4 100644 (file)
@@ -30,7 +30,7 @@
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1998
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1998
- *     Markus Armbruster, 2004-2008
+ *     Markus Armbruster, 2004-2011
  *     Ron Koenderink, 2006
  */
 
  *     Ron Koenderink, 2006
  */
 
@@ -148,7 +148,7 @@ draw_map(int bmap, char origin, int map_flags, struct nstr_sect *nsp)
        }
     }
     if (!bitmap)
        }
     }
     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");
     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) {
                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) {
                    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) {
        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) {
            bitinit2(nsp, bitmap, player->cnum);
        }
        while (nxtsct(nsp, &sect) && !player->aborted) {