0 gold pieces (trunk only)

Newsgroup discussion about the devnull tournament which started
today has pointed out that ``d4294967296$'' would cause getobj() to create
a gold piece object with quantity 0 which then got dropped to the floor.
(It's specific to gold; other types of objects don't behave that way.)
Also, wrapping which went past negative and zero all the way to positive
again (like 429496729*10+7, yielding 1) wasn't detected.
This commit is contained in:
nethack.rankin
2007-11-01 19:24:19 +00:00
parent 408a36bc5f
commit 7c860335c1
2 changed files with 31 additions and 18 deletions
+1
View File
@@ -267,6 +267,7 @@ tin contents can now sometimes be accessed on the same turn that the tin
starts being opened; when not, the opening feedback is more accurate starts being opened; when not, the opening feedback is more accurate
Nth adjustment of feedback when observing a pet eating Nth adjustment of feedback when observing a pet eating
monsters who want the Amulet won't attack temple priests to try to get it monsters who want the Amulet won't attack temple priests to try to get it
it was possible to generate an object of 0 gold pieces by dropping 2**32 gold
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
+30 -18
View File
@@ -1,4 +1,4 @@
/* SCCS Id: @(#)invent.c 3.5 2007/06/04 */ /* SCCS Id: @(#)invent.c 3.5 2007/11/01 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -828,8 +828,8 @@ register const char *let,*word;
boolean allownone = FALSE; boolean allownone = FALSE;
boolean useboulder = FALSE; boolean useboulder = FALSE;
xchar foox = 0; xchar foox = 0;
long cnt; long cnt, prevcnt;
boolean prezero = FALSE; boolean prezero;
long dummymask; long dummymask;
if(*let == ALLOW_COUNT) let++, allowcnt = 1; if(*let == ALLOW_COUNT) let++, allowcnt = 1;
@@ -1023,6 +1023,7 @@ register const char *let,*word;
for(;;) { for(;;) {
cnt = 0; cnt = 0;
if (allowcnt == 2) allowcnt = 1; /* abort previous count */ if (allowcnt == 2) allowcnt = 1; /* abort previous count */
prezero = FALSE;
if(!buf[0]) { if(!buf[0]) {
Sprintf(qbuf, "What do you want to %s? [*]", word); Sprintf(qbuf, "What do you want to %s? [*]", word);
} else { } else {
@@ -1035,18 +1036,28 @@ register const char *let,*word;
else else
#endif #endif
ilet = yn_function(qbuf, (char *)0, '\0'); ilet = yn_function(qbuf, (char *)0, '\0');
if(ilet == '0') prezero = TRUE; if (digit(ilet) && !allowcnt) {
while(digit(ilet) && allowcnt) { pline("No count allowed with this command.");
#ifdef REDO continue;
if (ilet != '?' && ilet != '*') savech(ilet);
#endif
cnt = 10*cnt + (ilet - '0');
allowcnt = 2; /* signal presence of cnt */
ilet = readchar();
} }
if(digit(ilet)) { if (ilet == '0') prezero = TRUE;
pline("No count allowed with this command."); while (digit(ilet)) {
continue; #ifdef REDO
if (ilet != '?' && ilet != '*') savech(ilet);
#endif
/* accumulate unless cnt has overflowed */
if (allowcnt < 3) {
prevcnt = cnt;
cnt = 10L * cnt + (long)(ilet - '0');
/* signal presence of cnt */
allowcnt = (cnt >= prevcnt) ? 2 : 3;
}
ilet = readchar();
}
if (allowcnt == 3) {
/* overflow detected; force cnt to be invalid */
cnt = -1L;
allowcnt = 2;
} }
if(index(quitchars,ilet)) { if(index(quitchars,ilet)) {
if(flags.verbose) if(flags.verbose)
@@ -1066,16 +1077,17 @@ register const char *let,*word;
return(struct obj *)0; return(struct obj *)0;
#endif #endif
} }
if(cnt == 0 && prezero) return((struct obj *)0);
/* Historic note: early Nethack had a bug which was /* Historic note: early Nethack had a bug which was
* first reported for Larn, where trying to drop 2^32-n * first reported for Larn, where trying to drop 2^32-n
* gold pieces was allowed, and did interesting things * gold pieces was allowed, and did interesting things
* to your money supply. The LRS is the tax bureau * to your money supply. The LRS is the tax bureau
* from Larn. * from Larn.
*/ */
if(cnt < 0) { if (cnt <= 0) {
pline_The("LRS would be very interested to know you have that much."); if (cnt < 0 || !prezero)
return(struct obj *)0; pline_The(
"LRS would be very interested to know you have that much.");
return (struct obj *)0;
} }
#ifndef GOLDOBJ #ifndef GOLDOBJ