diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 945ac8f57..1c5b9edfa 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.239 $ $NHDT-Date: 1548695445 2019/01/28 17:10:45 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.242 $ $NHDT-Date: 1548978603 2019/01/31 23:50:03 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, @@ -355,6 +355,10 @@ hero poly'd into creature with hug attack could hug a long worm's tail which smudging of an engraving has been relocated to after a succesful move and both your former location and your resulting location are subject to the smudging +monster with multiple items in inventory could trigger 'dealloc_obj with nobj' + panic when turned into a statue if separate mon->minvent items merged +lock picking context could end up with stale container pointer if container + being forced/unlocked/locked got destroyed or sent to another level Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/botl.c b/src/botl.c index 30719af07..075385250 100644 --- a/src/botl.c +++ b/src/botl.c @@ -3030,8 +3030,8 @@ choose_value: op, aval.a_int, is_out_of_range); goto choose_value; } else if (dt == ANY_LONG - && (aval.a_long < (lt_gt_eq == GT_VALUE) ? -1L - : (lt_gt_eq == LT_VALUE) ? 1L : 0L)) { + && (aval.a_long < ((lt_gt_eq == GT_VALUE) ? -1L + : (lt_gt_eq == LT_VALUE) ? 1L : 0L))) { pline("%s'%s%ld'%s", threshold_value, op, aval.a_long, is_out_of_range); goto choose_value; diff --git a/src/cmd.c b/src/cmd.c index 4d81d7088..b86ff65b7 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1547512504 2019/01/15 00:35:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.328 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1548978603 2019/01/31 23:50:03 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.330 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -810,7 +810,7 @@ wiz_makemap(VOID_ARGS) unplacebc(); } /* reset lock picking unless it's for a carried container */ - maybe_reset_pick(); + maybe_reset_pick((struct obj *) 0); /* reset interrupted digging if it was taking place on this level */ if (on_level(&g.context.digging.level, &u.uz)) (void) memset((genericptr_t) &g.context.digging, 0, diff --git a/src/do.c b/src/do.c index 1439cbcd9..629028c1d 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1547680082 2019/01/16 23:08:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.186 $ */ +/* NetHack 3.6 do.c $NHDT-Date: 1548978604 2019/01/31 23:50:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.189 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1315,7 +1315,7 @@ boolean at_stairs, falling, portal; 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(); + maybe_reset_pick((struct obj *) 0); reset_trapset(); /* even if to-be-armed trap obj is accompanying hero */ iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination cache */ g.context.polearm.hitmon = (struct monst *) 0; /* polearm target */ diff --git a/src/lock.c b/src/lock.c index 9f71e20da..f84dd6bd7 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 lock.c $NHDT-Date: 1547086531 2019/01/10 02:15:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.83 $ */ +/* NetHack 3.6 lock.c $NHDT-Date: 1548978605 2019/01/31 23:50:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.84 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -244,10 +244,14 @@ forcelock(VOID_ARGS) return 1; /* still busy */ You("succeed in forcing the lock."); + exercise(g.xlock.picktyp ? A_DEX : A_STR, TRUE); + /* breakchestlock() might destroy g.xlock.box; if so, g.xlock context will + be cleared (delobj -> obfree -> maybe_reset_pick); but it might not, + so explicitly clear that manually */ breakchestlock(g.xlock.box, (boolean) (!g.xlock.picktyp && !rn2(3))); + reset_pick(); /* lock-picking context is no longer valid */ - exercise((g.xlock.picktyp) ? A_DEX : A_STR, TRUE); - return ((g.xlock.usedtime = 0)); + return 0; } void @@ -255,15 +259,28 @@ reset_pick() { g.xlock.usedtime = g.xlock.chance = g.xlock.picktyp = 0; g.xlock.magic_key = FALSE; - g.xlock.door = 0; - g.xlock.box = 0; + g.xlock.door = (struct rm *) 0; + g.xlock.box = (struct obj *) 0; } -/* level change; don't reset if hero is carrying xlock.box with him/her */ +/* level change or object deletion; context may no longer be valid */ void -maybe_reset_pick() +maybe_reset_pick(container) +struct obj *container; /* passed from obfree() */ { - if (!g.xlock.box || !carried(g.xlock.box)) + /* + * If a specific container, only clear context if it is for that + * particular container (which is being deleted). Other stuff on + * the current dungeon level remains valid. + * However if 'container' is Null, clear context if not carrying + * g.xlock.box (which might be Null if context is for a door). + * Used for changing levels, where a floor container or a door is + * being left behind and won't be valid on the new level but a + * carried container will still be. There might not be any context, + * in which case redundantly clearing it is harmless. + */ + if (container ? (container == g.xlock.box) + : (!g.xlock.box || !carried(g.xlock.box))) reset_pick(); } diff --git a/src/mkobj.c b/src/mkobj.c index 900a49ac3..79053e041 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1547086532 2019/01/10 02:15:32 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.141 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1548978605 2019/01/31 23:50:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.142 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2076,6 +2076,10 @@ struct obj *obj; if (obj->where != OBJ_FREE) panic("add_to_migration: obj not free"); + /* lock picking context becomes stale if it's for this object */ + if (Is_container(obj)) + maybe_reset_pick(obj); + obj->where = OBJ_MIGRATING; obj->nobj = g.migrating_objs; g.migrating_objs = obj; diff --git a/src/mon.c b/src/mon.c index 03bf24fa1..9eb7aa658 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1548208236 2019/01/23 01:50:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.277 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1548937318 2019/01/31 12:21:58 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.278 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2211,6 +2211,7 @@ struct monst *mdef; otmp = oname(otmp, MNAME(mdef)); while ((obj = oldminvent) != 0) { oldminvent = obj->nobj; + obj->nobj = 0; /* avoid merged-> obfree-> dealloc_obj-> panic */ (void) add_to_container(otmp, obj); } /* Archeologists should not break unique statues */ diff --git a/src/options.c b/src/options.c index d83bd49e5..8486e1cbc 100644 --- a/src/options.c +++ b/src/options.c @@ -3291,8 +3291,10 @@ boolean tinitial, tfrom_file; } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { return FALSE; } - if (!assign_videocolors(opts)) /* TODO: error msg */ + if (!assign_videocolors(opts)) { + config_error_add("Unknown error handling '%s'", fullname); return FALSE; + } return retval; } /* videoshades:string */ @@ -3306,8 +3308,10 @@ boolean tinitial, tfrom_file; } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { return FALSE; } - if (!assign_videoshades(opts)) /* TODO: error msg */ + if (!assign_videoshades(opts)) { + config_error_add("Unknown error handling '%s'", fullname); return FALSE; + } return retval; } #endif /* VIDEOSHADES */ @@ -3324,8 +3328,10 @@ boolean tinitial, tfrom_file; } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { return FALSE; } - if (!assign_video(opts)) /* TODO: error msg */ + if (!assign_video(opts)) { + config_error_add("Unknown error handling '%s'", fullname); return FALSE; + } return retval; } #endif /* NO_TERMS */ @@ -3340,8 +3346,10 @@ boolean tinitial, tfrom_file; } else if (!(opts = string_for_env_opt(fullname, opts, FALSE))) { return FALSE; } - if (!assign_soundcard(opts)) /* TODO: error msg */ + if (!assign_soundcard(opts)) { + config_error_add("Unknown error handling '%s'", fullname); return FALSE; + } return retval; } #endif /* MSDOS */ @@ -3565,10 +3573,14 @@ boolean tinitial, tfrom_file; if (duplicate) complain_about_duplicate(opts, 1); if ((op = string_for_opt(opts, FALSE)) != 0) { - if (!wc_set_window_colors(op)) /* TODO: error msg*/ + if (!wc_set_window_colors(op)) { + config_error_add("Could not set %s '%s'", fullname, op); return FALSE; - } else if (negated) + } + } else if (negated) { bad_negation(fullname, TRUE); + return FALSE; + } return retval; } #ifdef CURSES_GRAPHICS @@ -3578,8 +3590,10 @@ boolean tinitial, tfrom_file; if (match_optname(opts, fullname, sizeof "term_cols" - 1, TRUE)) { op = string_for_opt(opts, negated); iflags.wc2_term_cols = atoi(op); - if (negated) - bad_negation(fullname, FALSE); + if (negated) { + bad_negation(fullname, FALSE); + return FALSE; + } return retval; } @@ -3589,8 +3603,10 @@ boolean tinitial, tfrom_file; if (match_optname(opts, fullname, sizeof "term_rows" - 1, TRUE)) { op = string_for_opt(opts, negated); iflags.wc2_term_rows = atoi(op); - if (negated) + if (negated) { bad_negation(fullname, FALSE); + return FALSE; + } return retval; } @@ -3602,16 +3618,20 @@ boolean tinitial, tfrom_file; if (op && !negated) { #ifdef CURSES_GRAPHICS iflags.wc2_petattr = curses_read_attrs(op); - if (!curses_read_attrs(op)) + if (!curses_read_attrs(op)) { config_error_add("Unknown %s parameter '%s'", fullname, opts); return FALSE; + } #else /* non-curses windowports will not use this flag anyway * but the above will not compile if we don't have curses. * Just set it to a sensible default: */ iflags.wc2_petattr = ATR_INVERSE #endif - } else if (negated) bad_negation(fullname, TRUE); + } else if (negated) { + bad_negation(fullname, TRUE); + return FALSE; + } return retval; } @@ -3620,9 +3640,10 @@ boolean tinitial, tfrom_file; fullname = "windowborders"; if (match_optname(opts, fullname, sizeof "windowborders" - 1, TRUE)) { op = string_for_opt(opts, negated); - if (negated && op) + if (negated && op) { bad_negation(fullname, TRUE); - else { + return FALSE; + } else { if (negated) iflags.wc2_windowborders = 2; /* Off */ else if (!op) @@ -3633,6 +3654,7 @@ boolean tinitial, tfrom_file; || (iflags.wc2_windowborders < 1)) { iflags.wc2_windowborders = 0; config_error_add("Badoption - windowborders %s.", opts); + return FALSE; } } return retval; diff --git a/src/shk.c b/src/shk.c index 7f9b5d324..98830853d 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 shk.c $NHDT-Date: 1547849604 2019/01/18 22:13:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.153 $ */ +/* NetHack 3.6 shk.c $NHDT-Date: 1548978606 2019/01/31 23:50:06 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.154 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -911,6 +911,8 @@ register struct obj *obj, *merge; book_disappears(obj); if (Has_contents(obj)) delete_contents(obj); + if (Is_container(obj)) + maybe_reset_pick(obj); shkp = 0; if (obj->unpaid) { diff --git a/util/makedefs.c b/util/makedefs.c index 53015a2a0..4b8ae3665 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -111,15 +111,6 @@ static const char SCCS_Id[] UNUSED = "@(#)makedefs.c\t3.6\t2018/03/02"; #endif /* else !MAC */ #endif /* else !AMIGA */ -#if !defined(STATUS_HILITES) && defined(WIN32) -#define FIX_SAMPLECONFIG -#endif - -#ifdef WIN32 -#define SAMPLE_CONFIGFILE "../sys/winnt/defaults.nh" -#define FIXED_CONFIGFILE "./fixed_defaults.nh" -#endif - static const char *Dont_Edit_Code = "/* This source file is generated by 'makedefs'. Do not edit. */\n", @@ -145,7 +136,9 @@ static char xclear[MAX_ROW][MAX_COL]; #endif /*-end of vision defs-*/ -static char filename[600]; +#define MAXFNAMELEN 600 + +static char filename[MAXFNAMELEN]; #ifdef FILE_PREFIX /* if defined, a first argument not starting with - is @@ -171,9 +164,6 @@ void NDECL(do_questtxt); void NDECL(do_rumors); void NDECL(do_oracles); void NDECL(do_vision); -#ifdef WIN32 -void NDECL(do_fix_sampleconfig); -#endif extern void NDECL(monst_globals_init); /* monst.c */ extern void NDECL(objects_globals_init); /* objects.c */ @@ -365,12 +355,7 @@ char *options; case 'Z': do_vision(); break; -#ifdef WIN32 - case 'c': - case 'C': - do_fix_sampleconfig(); - break; -#endif + default: Fprintf(stderr, "Unknown option '%c'.\n", *options); (void) fflush(stderr); @@ -891,7 +876,7 @@ int *rumor_count; long *rumor_size; unsigned long old_rumor_offset; { - char infile[600]; + char infile[MAXFNAMELEN]; char *line; unsigned long rumor_offset; @@ -990,7 +975,7 @@ do_rumors() char *line; static const char rumors_header[] = "%s%04d,%06ld,%06lx;%04d,%06ld,%06lx;0,0,%06lx\n"; - char tempfile[600]; + char tempfile[MAXFNAMELEN]; int true_rumor_count, false_rumor_count; long true_rumor_size, false_rumor_size; unsigned long true_rumor_offset, false_rumor_offset, eof_offset; @@ -1033,7 +1018,7 @@ do_rumors() goto rumors_failure; /* get ready to transfer the contents of temp file to output file */ - line = malloc(256); + line = malloc(BUFSZ + MAXFNAMELEN); Sprintf(line, "rewind of \"%s\"", tempfile); if (rewind(tfp) != 0) { perror(line); @@ -1408,7 +1393,7 @@ char *githash, *gitbranch; { FILE *gifp; size_t len; - char infile[600]; + char infile[MAXFNAMELEN]; char *line, *strval, *opt, *c, *end; boolean havebranch = FALSE, havehash = FALSE; @@ -1461,45 +1446,6 @@ char *githash, *gitbranch; return FALSE; } -#ifdef WIN32 -void -do_fix_sampleconfig() -{ - FILE *scfp, *ofcfp; - char fixedline[600]; - char *line; - - if (!(scfp = fopen(SAMPLE_CONFIGFILE, RDTMODE))) { - return; - } - if (!(ofcfp = fopen(FIXED_CONFIGFILE, WRTMODE))) { - return; - } - - /* read the sample config file */ - while ((line = fgetline(scfp)) != 0) { - /* comment out the STATUS_HILITES related lines */ - if (strlen(line) < (600 - 1)) { - if (strstr(line, "statushilites") || strstr(line, "hilite_status:")) { -#ifdef FIX_SAMPLECONFIG - fixedline[0] = '#'; - Strcpy(&fixedline[1], line); -#else - Strcpy(fixedline, line); -#endif - fputs(fixedline, ofcfp); - } else { - fputs(line, ofcfp); - } - } - free(line); - } - Fclose(scfp); - Fclose(ofcfp); - return; -} -#endif /* WIN32 */ - static int case_insensitive_comp(s1, s2) const char *s1; @@ -1970,7 +1916,7 @@ do_data() Fclose(ifp); /* all done with original input file */ /* reprocess the scratch file; 1st format an error msg, just in case */ - line = malloc(256); + line = malloc(BUFSZ + MAXFNAMELEN); Sprintf(line, "rewind of \"%s\"", tempfile); if (rewind(tfp) != 0) goto dead_data; @@ -1986,7 +1932,7 @@ do_data() Unlink(tempfile); /* remove it */ /* update the first record of the output file; prepare error msg 1st */ - line = malloc(256); + line = malloc(BUFSZ + MAXFNAMELEN); Sprintf(line, "rewind of \"%s\"", filename); ok = (rewind(ofp) == 0); if (ok) { @@ -2143,7 +2089,7 @@ do_oracles() Fclose(ifp); /* all done with original input file */ /* reprocess the scratch file; 1st format an error msg, just in case */ - line = malloc(256); + line = malloc(BUFSZ + MAXFNAMELEN); Sprintf(line, "rewind of \"%s\"", tempfile); if (rewind(tfp) != 0) goto dead_data; @@ -2159,7 +2105,7 @@ do_oracles() Unlink(tempfile); /* remove it */ /* update the first record of the output file; prepare error msg 1st */ - line = malloc(256); + line = malloc(BUFSZ + MAXFNAMELEN); Sprintf(line, "rewind of \"%s\"", filename); ok = (rewind(ofp) == 0); if (ok) {