redo nowrap_add()

Yahoo!'s mailer delivered the report about nowrap_add() to my spam
folder, apparently because it thinks that the signature attachments
"may contain harmful content".  :-(

nowrap_add() checks for signed overflow after the fact, so after
undefined behavior if that happens.

This rewrites nowrap_add() and moves it from end.c to integer.h.

I haven't generated any values big enough to exercise it, but the
algorithm is straightforward so I'll take it on faith.
This commit is contained in:
PatR
2024-07-07 17:34:37 -07:00
parent 0447a1f107
commit 8073c40477
3 changed files with 20 additions and 16 deletions
+6 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.7 integer.h $NHDT-Date: 1717967331 2024/06/09 21:08:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* NetHack 3.7 integer.h $NHDT-Date: 1720397754 2024/07/08 00:15:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */
/* Copyright (c) 2016 by Michael Allison */ /* Copyright (c) 2016 by Michael Allison */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -110,4 +110,9 @@ typedef uint64_t uint64;
? (L) * 10L + (D) \ ? (L) * 10L + (D) \
: -1L) : -1L)
/* add a and b, return max long value if overflow would have occurred;
assumes that both a and b are non-negative; caller should apply
cast(s) to (long) in the arguments if any are needed */
#define nowrap_add(a,b) ((a) <= (LONG_MAX - (b)) ? ((a) + (b)) : LONG_MAX)
#endif /* INTEGER_H */ #endif /* INTEGER_H */
+13 -10
View File
@@ -1,4 +1,4 @@
/* NetHack 3.7 botl.c $NHDT-Date: 1694893342 2023/09/16 19:42:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ /* NetHack 3.7 botl.c $NHDT-Date: 1720397739 2024/07/08 00:15:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.264 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */ /*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -423,17 +423,20 @@ long
botl_score(void) botl_score(void)
{ {
long deepest = deepest_lev_reached(FALSE); long deepest = deepest_lev_reached(FALSE);
long utotal; long umoney, depthbonus;
/* hidden_gold(False): only gold in containers whose contents are known */ /* hidden_gold(False): only gold in containers whose contents are known */
utotal = money_cnt(gi.invent) + hidden_gold(FALSE); umoney = money_cnt(gi.invent) + hidden_gold(FALSE);
if ((utotal -= u.umoney0) < 0L) /* don't include initial gold; don't impose penalty if its all gone */
utotal = 0L; if ((umoney -= u.umoney0) < 0L)
utotal += u.urexp + (50 * (deepest - 1)) umoney = 0L;
+ (deepest > 30 ? 10000 : deepest > 20 ? 1000 * (deepest - 20) : 0); depthbonus = 50 * (deepest - 1)
if (utotal < u.urexp) + (deepest > 30) ? 10000
utotal = LONG_MAX; /* wrap around */ : (deepest > 20) ? 1000 * (deepest - 20)
return utotal; : 0;
/* neither umoney nor depthbonus can grow unusually big (gold due to
weight); u.urexp might */
return nowrap_add(u.urexp, umoney + depthbonus);
} }
#endif /* SCORE_ON_BOTL */ #endif /* SCORE_ON_BOTL */
+1 -5
View File
@@ -1,4 +1,4 @@
/* NetHack 3.7 end.c $NHDT-Date: 1711735821 2024/03/29 18:10:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.313 $ */ /* NetHack 3.7 end.c $NHDT-Date: 1720397752 2024/07/08 00:15:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -15,10 +15,6 @@
#endif #endif
#include "dlb.h" #include "dlb.h"
/* add b to long a, convert wraparound to max value */
#define nowrap_add(a, b) (a = ((a + b) < 0 ? LONG_MAX : (a + b)))
#ifndef NO_SIGNAL #ifndef NO_SIGNAL
staticfn void done_intr(int); staticfn void done_intr(int);
# if defined(UNIX) || defined(VMS) || defined(__EMX__) # if defined(UNIX) || defined(VMS) || defined(__EMX__)