Package: bsdgames-nonfree
Version: 2.17-6build1
Severity: normal
Tags: patch

Dear Maintainer,

I was reading the source for Rogue when I noticed the following curious
condition in the `create_monster` function:

                if (((row == rogue.row) && (col = rogue.col)) ||
                                (row < MIN_ROW) || (row > (DROWS-2)) ||
                                (col < 0) || (col > (DCOLS-1))) {
                        continue;
                }

The `(col = rogue.col)` looks suspect to me; should this perhaps read
`(col == rogue.col)`?

All other callers of `rand_around` do properly check `col == rogue.col`
rather than assigning to it (if they attempt to check it at all).

I'm pretty sure that I actually just hit this bug in game. I was in a
1-high tunnel and read a scroll of create monster, which failed:

        $ head rogue.screen
        you hear a faint cry of anguish in the distance
                                       -----------------
                        --------       |               +#################@
                        |      |     ##+      %        |
                        |      +###### |               |
                        ---+----       -----------------
                           #
                           #
                           #
                           #

>From this code, we can see that the only place that the monster could
have spawned was the tile to the left of the player, but that iteration
of the loop was skipped because `(col = rogue.col)` evaluates to 65,
which is true.

Please find enclosed a patch, should you choose to use it. (Consider it
released into the public domain; let me know if you want a specific
license.)

-- System Information:
Debian Release: stretch/sid
  APT prefers xenial-updates
  APT policy: (500, 'xenial-updates'), (500, 'xenial-security'), (500, 
'xenial-backports'), (500, 'xenial')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.10.0-32-generic (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages bsdgames-nonfree depends on:
ii  libc6        2.23-0ubuntu11
ii  libncurses5  6.0+20160213-1ubuntu1
ii  libtinfo5    6.0+20160213-1ubuntu1

bsdgames-nonfree recommends no packages.

Versions of packages bsdgames-nonfree suggests:
pn  bsdgames  <none>

-- no debconf information
>From 3b3ff8bfb04224866b7573e0bf620299313ca9b4 Mon Sep 17 00:00:00 2001
From: William Chargin <wchar...@gmail.com>
Date: Tue, 31 Mar 2020 19:39:13 -0700
Subject: [PATCH] monster: permit spawning on same row as player

Due to a typo, the `(row == rogue.row) && (col = rogue.col)` check is
effectively equivalent to `(row == rogue.row)`. This prevents monsters
from spawning on the same row as the player when a scroll of create
monster is read.

To reproduce, play Rogue until you find a scroll of create monster, then
enter a horizontal tunnel such that the only adjacent spaces are in the
same row as the player. Read the scroll, and note that you "hear a faint
cry of anger in the distance".
---
 rogue/monster.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rogue/monster.c b/rogue/monster.c
index 2bcc25d..30b0705 100644
--- a/rogue/monster.c
+++ b/rogue/monster.c
@@ -688,7 +688,7 @@ create_monster()
 
 	for (i = 0; i < 9; i++) {
 		rand_around(i, &row, &col);
-		if (((row == rogue.row) && (col = rogue.col)) ||
+		if (((row == rogue.row) && (col == rogue.col)) ||
 				(row < MIN_ROW) || (row > (DROWS-2)) ||
 				(col < 0) || (col > (DCOLS-1))) {
 			continue;
-- 
2.26.0

Reply via email to