diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 53ba866ea..4073cef20 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -236,6 +236,12 @@ to emphasize that it's not a light source, change description of wielded Sting from "(glowing)" to nothing (not warm enough to feel) when blind glowing Sting quivers if hero becomes blind and quivering Sting glows if blindness ends; it worked for timed blindness but not for blindfold +weapon (wielded pie, egg, potion, boomerang) might be destroyed when hitting a + long worm, then freed memory was accessed to decide whether to cut it +level change after being interruped locking or unlocking a container might + access freed memory +if a restore attempt failed and a new game was started instead, it would use + stale context from old game if restoration got far enough to load that Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository @@ -258,6 +264,8 @@ buliding with EXTRA_SANITY_CHECKS enabled would issue "no monster to remove" changing Sting's description to be "(weapon in hand) (light blue aura)" was too close to feedback when objects become blessed; change it again, to "(weapon in hand, flickering/glimmering/gleaming light blue)" +fix bit-use collision between WC2_TERM_SIZE and WC2_RESET_STATUS in + include/winprocs.h following a recent merge tty: turn off an optimization that is the suspected cause of Windows reported partial status lines following level changes tty: ensure that current status fields are always copied to prior status diff --git a/include/extern.h b/include/extern.h index 16b10859b..4f1c8d6fa 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1543745352 2018/12/02 10:09:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.664 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1543892214 2018/12/04 02:56:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.665 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2834,7 +2834,7 @@ E void FDECL(worm_move, (struct monst *)); E void FDECL(worm_nomove, (struct monst *)); E void FDECL(wormgone, (struct monst *)); E void FDECL(wormhitu, (struct monst *)); -E void FDECL(cutworm, (struct monst *, XCHAR_P, XCHAR_P, struct obj *)); +E void FDECL(cutworm, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P)); E void FDECL(see_wsegs, (struct monst *)); E void FDECL(detect_wsegs, (struct monst *, BOOLEAN_P)); E void FDECL(save_worm, (int, int)); diff --git a/include/winprocs.h b/include/winprocs.h index 316af5171..ddfef409d 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -216,10 +216,10 @@ extern after updating status window fields */ #define WC2_RESET_STATUS 0x0100L /* 09 call status_update(BL_RESET) to indicate draw everything */ -#define WC2_TERM_SIZE 0x0100L /* 10 support setting terminal size */ -#define WC2_WINDOWBORDERS 0x0200L /* 11 display borders on nh windows */ -#define WC2_PETATTR 0x0400L /* 12 attributes for hilite_pet */ -#define WC2_GUICOLOR 0x0800L /* 13 display colours outside map win */ +#define WC2_TERM_SIZE 0x0200L /* 10 support setting terminal size */ +#define WC2_WINDOWBORDERS 0x0400L /* 11 display borders on nh windows */ +#define WC2_PETATTR 0x0800L /* 12 attributes for hilite_pet */ +#define WC2_GUICOLOR 0x1000L /* 13 display colours outside map win */ /* 19 free bits */ #define ALIGN_LEFT 1 diff --git a/src/cmd.c b/src/cmd.c index 92b2fc0d2..8924923da 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1543797825 2018/12/03 00:43:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.312 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1543972186 2018/12/05 01:09:46 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.313 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -5694,7 +5694,7 @@ dotravel(VOID_ARGS) cmd[1] = 0; cc.x = iflags.travelcc.x; cc.y = iflags.travelcc.y; - if (cc.x == -1 && cc.y == -1) { + if (cc.x == 0 && cc.y == 0) { /* No cached destination, start attempt from current position */ cc.x = u.ux; cc.y = u.uy; diff --git a/src/do.c b/src/do.c index 4817d150a..febfcf9b5 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1543052696 2018/11/24 09:44:56 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.175 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1543972190 2018/12/05 01:09:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.176 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1237,6 +1237,17 @@ boolean at_stairs, falling, portal; if (fd < 0) return; + /* discard context which applies to the level we're leaving; + for lock-picking, container may be carried, in which case we + keep context; if on the floor, it's about to be saved+freed and + maybe_reset_pick() needs to do its carried() check before that */ + maybe_reset_pick(); + reset_trapset(); /* even if to-be-armed trap obj is accompanying hero */ + iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination cache */ + context.polearm.hitmon = (struct monst *) 0; /* polearm target */ + /* digging context is level-aware and can actually be resumed if + hero returns to the previous level without any intervening dig */ + if (falling) /* assuming this is only trap door or hole */ impact_drop((struct obj *) 0, u.ux, u.uy, newlevel->dlevel); @@ -1576,14 +1587,6 @@ boolean at_stairs, falling, portal; /* assume this will always return TRUE when changing level */ (void) in_out_region(u.ux, u.uy); (void) pickup(1); - - /* discard context which applied to previous level */ - maybe_reset_pick(); /* for door or for box not accompanying hero */ - reset_trapset(); /* even if to-be-armed trap obj is accompanying hero */ - iflags.travelcc.x = iflags.travelcc.y = -1; /* travel destination cache */ - context.polearm.hitmon = (struct monst *) 0; /* polearm target */ - /* digging context is level-aware and can actually be resumed if - hero returns to the previous level without any intervening dig */ } STATIC_OVL void diff --git a/src/dothrow.c b/src/dothrow.c index d40857447..e55c9b7d6 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dothrow.c $NHDT-Date: 1525012611 2018/04/29 14:36:51 $ $NHDT-Branch: master $:$NHDT-Revision: 1.137 $ */ +/* NetHack 3.6 dothrow.c $NHDT-Date: 1543892215 2018/12/04 02:56:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.152 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1652,13 +1652,16 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */ } if (tmp >= dieroll) { - boolean wasthrown = (thrownobj != 0); + boolean wasthrown = (thrownobj != 0), + /* remember weapon attribute; hmon() might destroy obj */ + chopper = is_axe(obj); /* attack hits mon */ if (hmode == HMON_APPLIED) u.uconduct.weaphit++; if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */ - cutworm(mon, bhitpos.x, bhitpos.y, obj); + if (mon->wormno) + cutworm(mon, bhitpos.x, bhitpos.y, chopper); } exercise(A_DEX, TRUE); /* if hero was swallowed and projectile killed the engulfer, @@ -1668,8 +1671,9 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */ if (wasthrown && !thrownobj) return 1; - /* projectiles other than magic stones - sometimes disappear when thrown */ + /* projectiles other than magic stones sometimes disappear + when thrown; projectiles aren't among the types of weapon + that hmon() might have destroyed so obj is intact */ if (objects[otyp].oc_skill < P_NONE && objects[otyp].oc_skill > -P_BOOMERANG && !objects[otyp].oc_magic) { diff --git a/src/hack.c b/src/hack.c index 7a5e48116..c0c0313f2 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.c $NHDT-Date: 1540591769 2018/10/26 22:09:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.194 $ */ +/* NetHack 3.6 hack.c $NHDT-Date: 1543972190 2018/12/05 01:09:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.200 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -923,7 +923,7 @@ int mode; u.dx = u.tx - u.ux; u.dy = u.ty - u.uy; nomul(0); - iflags.travelcc.x = iflags.travelcc.y = -1; + iflags.travelcc.x = iflags.travelcc.y = 0; } return TRUE; } @@ -1045,7 +1045,7 @@ int mode; nomul(0); /* reset run so domove run checks work */ context.run = 8; - iflags.travelcc.x = iflags.travelcc.y = -1; + iflags.travelcc.x = iflags.travelcc.y = 0; } return TRUE; } diff --git a/src/options.c b/src/options.c index 8be8cfcd3..d4b7daf4d 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1543395749 2018/11/28 09:02:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.334 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1543972192 2018/12/05 01:09:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.335 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -747,8 +747,6 @@ initoptions_init() warnsyms[i] = def_warnsyms[i].sym; iflags.bouldersym = 0; - iflags.travelcc.x = iflags.travelcc.y = -1; - /* for "special achievement" tracking (see obj.h, create_object(sp_lev.c), addinv_core1(invent.c) */ iflags.mines_prize_type = LUCKSTONE; diff --git a/src/restore.c b/src/restore.c index 25604f10d..e9f25d72c 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 restore.c $NHDT-Date: 1542798626 2018/11/21 11:10:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.109 $ */ +/* NetHack 3.6 restore.c $NHDT-Date: 1543972193 2018/12/05 01:09:53 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -539,6 +539,7 @@ unsigned int *stuckid, *steedid; #ifdef SYSFLAGS struct sysflag newgamesysflags; #endif + struct context_info newgamecontext; /* all 0, but has some pointers */ struct obj *otmp, *tmp_bc; char timebuf[15]; unsigned long uid; @@ -553,9 +554,15 @@ unsigned int *stuckid, *steedid; if (!wizard) return FALSE; } + + newgamecontext = context; /* copy statically init'd context */ mread(fd, (genericptr_t) &context, sizeof (struct context_info)); - if (context.warntype.speciesidx >= LOW_PM) - context.warntype.species = &mons[context.warntype.speciesidx]; + context.warntype.species = (context.warntype.speciesidx >= LOW_PM) + ? &mons[context.warntype.speciesidx] + : (struct permonst *) 0; + /* context.victual.piece, .tin.tin, .spellbook.book, and .polearm.hitmon + are pointers which get set to Null during save and will be recovered + via corresponding o_id or m_id while objs or mons are being restored */ /* we want to be able to revert to command line/environment/config file option values instead of keeping old save file option values @@ -625,6 +632,7 @@ unsigned int *stuckid, *steedid; #ifdef SYSFLAGS sysflags = newgamesysflags; #endif + context = newgamecontext; return FALSE; } /* in case hangup save occurred in midst of level change */ diff --git a/src/save.c b/src/save.c index 095890f05..18465966d 100644 --- a/src/save.c +++ b/src/save.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 save.c $NHDT-Date: 1489192905 2017/03/11 00:41:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.101 $ */ +/* NetHack 3.6 save.c $NHDT-Date: 1543972194 2018/12/05 01:09:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.115 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1035,37 +1035,22 @@ register struct obj *otmp; if (Has_contents(otmp)) saveobjchn(fd, otmp->cobj, mode); if (release_data(mode)) { - /* if (otmp->oclass == FOOD_CLASS) - * food_disappears(otmp); - */ /* - * If these are on the floor, the discarding could - * be because of a game save, or we could just be changing levels. + * If these are on the floor, the discarding could be + * due to game save, or we could just be changing levels. * Always invalidate the pointer, but ensure that we have * the o_id in order to restore the pointer on reload. */ if (otmp == context.victual.piece) { - /* Store the o_id of the victual if mismatched */ - if (context.victual.o_id != otmp->o_id) - context.victual.o_id = otmp->o_id; - /* invalidate the pointer; on reload it will get restored */ + context.victual.o_id = otmp->o_id; context.victual.piece = (struct obj *) 0; } if (otmp == context.tin.tin) { - /* Store the o_id of your tin */ - if (context.tin.o_id != otmp->o_id) - context.tin.o_id = otmp->o_id; - /* invalidate the pointer; on reload it will get restored */ + context.tin.o_id = otmp->o_id; context.tin.tin = (struct obj *) 0; } - /* if (otmp->oclass == SPBOOK_CLASS) - * book_disappears(otmp); - */ if (otmp == context.spbook.book) { - /* Store the o_id of your spellbook */ - if (context.spbook.o_id != otmp->o_id) - context.spbook.o_id = otmp->o_id; - /* invalidate the pointer; on reload it will get restored */ + context.spbook.o_id = otmp->o_id; context.spbook.book = (struct obj *) 0; } otmp->where = OBJ_FREE; /* set to free so dealloc will work */ diff --git a/src/uhitm.c b/src/uhitm.c index a14218543..0412bb599 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1542765366 2018/11/21 01:56:06 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.185 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1543892215 2018/12/04 02:56:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.195 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -449,7 +449,9 @@ int rollneeded, armorpenalty; /* for monks */ struct attack *uattk; int dieroll; { - register boolean malive = TRUE; + boolean malive = TRUE, + /* hmon() might destroy weapon; remember aspect for cutworm */ + slice_or_chop = (weapon && (is_blade(weapon) || is_axe(weapon))); if (override_confirmation) { /* this may need to be generalized if weapons other than @@ -490,7 +492,7 @@ int dieroll; u.uconduct.weaphit = oldweaphit; } if (mon->wormno && *mhit) - cutworm(mon, x, y, weapon); + cutworm(mon, x, y, slice_or_chop); } } return malive; diff --git a/src/worm.c b/src/worm.c index 4e9d144b1..faf257710 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 worm.c $NHDT-Date: 1456528599 2016/02/26 23:16:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 3.6 worm.c $NHDT-Date: 1543892216 2018/12/04 02:56:56 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -314,10 +314,10 @@ register struct monst *worm; * that both halves will survive. */ void -cutworm(worm, x, y, weap) +cutworm(worm, x, y, cuttier) struct monst *worm; xchar x, y; -struct obj *weap; +boolean cuttier; /* hit is by wielded blade or axe or by thrown axe */ { register struct wseg *curr, *new_tail; register struct monst *new_worm; @@ -330,12 +330,10 @@ struct obj *weap; if (x == worm->mx && y == worm->my) return; /* hit on head */ - /* cutting goes best with a bladed weapon */ - cut_chance = rnd(20); /* Normally 1-16 does not cut */ - /* Normally 17-20 does */ - - if (weap && is_blade(weap)) /* With a blade 1- 6 does not cut */ - cut_chance += 10; /* 7-20 does */ + /* cutting goes best with a cuttier weapon */ + cut_chance = rnd(20); /* Normally 1-16 does not cut, 17-20 does, */ + if (cuttier) + cut_chance += 10; /* with a blade 1- 6 does not cut, 7-20 does. */ if (cut_chance < 17) return; /* not good enough */