From 8ce7216a0c55b4424c1aeefbe27ba0ce27d04360 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Fri, 2 Sep 2005 06:00:44 +0000 Subject: [PATCH] fix M159 - crash at end of prayer Fix the crash caused by division by zero (attempt to compute rn2(0)) when deciding prayer boon for a character whose Luck went negative during the course of the prayer. triggered it by killing a shopkeeper with the ongoing damage from a scroll of stinking cloud; his non-chaotic character was branded a murderer and lost two points of Luck after the prayer was already in progress. (Prayers fail when Luck is already negative, so the code to pick a boon expects non-negative values; the fact that is always adds at least +2 leads to me to suspect that someone already realized that luck timeout on Friday 13th could result in Luck of -1 at the end of a successful prayer--that value doesn't trigger this crash.) --- doc/fixes34.4 | 1 + src/pray.c | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/doc/fixes34.4 b/doc/fixes34.4 index 6531f21bd..2c429a4a4 100644 --- a/doc/fixes34.4 +++ b/doc/fixes34.4 @@ -140,6 +140,7 @@ weaken "farming" strategy don't suppress corpse if you kill your own steed fix typo in tourist quest leader's greeting fix grammar for graveyard sounds when polymorphed +avoid divide by zero crash if Luck drops below -1 while a prayer is in progress Platform- and/or Interface-Specific Fixes diff --git a/src/pray.c b/src/pray.c index 500c82f6b..05d544d79 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)pray.c 3.5 2005/06/24 */ +/* SCCS Id: @(#)pray.c 3.5 2005/08/31 */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -844,8 +844,22 @@ pleased(g_align) /* if hero was in trouble, but got better, no special favor */ if (p_trouble == 0) pat_on_head = 1; } else { - int action = rn1(Luck + (on_altar() ? 3 + on_shrine() : 2), 1); - + int action, prayer_luck; + + /* Negative luck is normally impossible here (can_pray() forces + prayer failure in that situation), but it's possible for + Luck to drop during the period of prayer occupation and + become negative by the time we get here. [Reported case + was lawful character whose stinking cloud caused a delayed + killing of a peaceful human, triggering the "murderer" + penalty while successful prayer was in progress. It could + also happen due to inconvenient timing on Friday 13th, but + the magnitude there (-1) isn't big enough to cause trouble.] + We don't bother remembering start-of-prayer luck, just make + sure it's at least -1 so that Luck+2 is big enough to avoid + a divide by zero crash when generating a random number. */ + prayer_luck = max(Luck, -1); /* => (prayer_luck + 2 > 0) */ + action = rn1(prayer_luck + (on_altar() ? 3 + on_shrine() : 2), 1); if (!on_altar()) action = min(action, 3); if (u.ualign.record < STRIDENT) action = (u.ualign.record > 0 || !rnl(2)) ? 1 : 0; -- 2.50.1