From eb650c2811a870e69d13fce8abaf06d299ad3c53 Mon Sep 17 00:00:00 2001 From: Thomas Arp <357770+welcor@users.noreply.github.com> Date: Wed, 26 Feb 2020 00:39:29 +0100 Subject: [PATCH] GitHub issues 78 79 81 num aff flags off by one (#82) * Make sure all followers are free'd before freeing the character list Otherwise, the followers structs will point to free'd memory and the stop_follower call will attempt to dereference a free'd characters' followers list. * https://github.com/tbamud/tbamud/issues/79 typo * https://github.com/tbamud/tbamud/issues/81 nullpointer crash on syntax check run * NUM_AFF_FLAGS fix. Now, consistently, the NUM_AFF_FLAGS is used in the same way as other NUM_* variables. Specifically, the the number is consistent with how others are defined - 1 above the highest in the list. I would like to have removed the need to start from 1 instead of 0 as well, but the loading mechanism, and thus potentially a lot of existing object files, use 0 as a marker for "no flags set", and we can't easily fix that. So, the places we loop through the list, we still need to make sure we're stying within the [1;NUM_AFF_FLAGS) interval. Simultaneously, I've checked over the other flags, and it seems like the usage is pretty consistent there. Fixes https://github.com/tbamud/tbamud/issues/78 --- src/act.wizard.c | 2 +- src/dg_event.c | 3 ++- src/magic.c | 2 +- src/medit.c | 14 +++++++------- src/oedit.c | 2 +- src/players.c | 2 +- src/spec_procs.c | 2 +- src/structs.h | 6 +++--- src/utils.c | 5 ----- 9 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/act.wizard.c b/src/act.wizard.c index 5ae0cad..b0694ee 100644 --- a/src/act.wizard.c +++ b/src/act.wizard.c @@ -922,7 +922,7 @@ static void do_stat_character(struct char_data *ch, struct char_data *k) if (aff->bitvector[0] || aff->bitvector[1] || aff->bitvector[2] || aff->bitvector[3]) { if (aff->modifier) send_to_char(ch, ", "); - for (i=0; ibitvector, i)) { send_to_char(ch, "sets %s, ", affected_bits[i]); } diff --git a/src/dg_event.c b/src/dg_event.c index 06b6ca5..d146a8c 100644 --- a/src/dg_event.c +++ b/src/dg_event.c @@ -151,7 +151,8 @@ long event_time(struct event *event) /** Frees all events from event_q. */ void event_free_all(void) { - queue_free(event_q); + if (event_q != NULL) + queue_free(event_q); } /** Boolean function to tell whether an event is queued or not. Does this by diff --git a/src/magic.c b/src/magic.c index 7dd4abd..5882589 100644 --- a/src/magic.c +++ b/src/magic.c @@ -522,7 +522,7 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim, * and waiting for it to fade, for example. */ if (IS_NPC(victim) && !affected_by_spell(victim, spellnum)) { for (i = 0; i < MAX_SPELL_AFFECTS; i++) { - for (j=0; jcharacter); clear_screen(d); - /* +1 since AFF_FLAGS don't start at 0. */ - column_list(d->character, 0, affected_bits + 1, NUM_AFF_FLAGS, TRUE); + /* +1/-1 antics needed because AFF_FLAGS doesn't start at 0. */ + column_list(d->character, 0, affected_bits + 1, NUM_AFF_FLAGS - 1, TRUE); sprintbitarray(AFF_FLAGS(OLC_MOB(d)), affected_bits, AF_ARRAY_MAX, flags); write_to_output(d, "\r\nCurrent flags : %s%s%s\r\nEnter aff flags (0 to quit) : ", cyn, flags, nrm); @@ -577,8 +577,8 @@ void medit_parse(struct descriptor_data *d, char *arg) case 'q': case 'Q': if (OLC_VAL(d)) { /* Anything been changed? */ - write_to_output(d, "Do you wish to save your changes? : "); - OLC_MODE(d) = MEDIT_CONFIRM_SAVESTRING; + write_to_output(d, "Do you wish to save your changes? : "); + OLC_MODE(d) = MEDIT_CONFIRM_SAVESTRING; } else cleanup_olc(d, CLEANUP_ALL); return; @@ -603,8 +603,8 @@ void medit_parse(struct descriptor_data *d, char *arg) send_editor_help(d); write_to_output(d, "Enter mob description:\r\n\r\n"); if (OLC_MOB(d)->player.description) { - write_to_output(d, "%s", OLC_MOB(d)->player.description); - oldtext = strdup(OLC_MOB(d)->player.description); + write_to_output(d, "%s", OLC_MOB(d)->player.description); + oldtext = strdup(OLC_MOB(d)->player.description); } string_write(d, &OLC_MOB(d)->player.description, MAX_MOB_DESC, 0, oldtext); OLC_VAL(d) = 1; @@ -898,7 +898,7 @@ void medit_parse(struct descriptor_data *d, char *arg) case MEDIT_AFF_FLAGS: if ((i = atoi(arg)) <= 0) break; - else if (i <= NUM_AFF_FLAGS) + else if (i < NUM_AFF_FLAGS) TOGGLE_BIT_AR(AFF_FLAGS(OLC_MOB(d)), i); /* Remove unwanted bits right away. */ diff --git a/src/oedit.c b/src/oedit.c index bad0fe9..f7c4b7f 100644 --- a/src/oedit.c +++ b/src/oedit.c @@ -936,7 +936,7 @@ void oedit_parse(struct descriptor_data *d, char *arg) case OEDIT_PERM: if ((number = atoi(arg)) == 0) break; - if (number > 0 && number <= NUM_AFF_FLAGS) { + if (number > 0 && number < NUM_AFF_FLAGS) { /* Setting AFF_CHARM on objects like this is dangerous. */ if (number != AFF_CHARM) { TOGGLE_BIT_AR(GET_OBJ_AFFECT(OLC_OBJ(d)), number); diff --git a/src/players.c b/src/players.c index 3ed0614..1e76197 100644 --- a/src/players.c +++ b/src/players.c @@ -847,7 +847,7 @@ static void load_affects(FILE *fl, struct char_data *ch) af.bitvector[2] = num7; af.bitvector[3] = num8; } else if (n_vars == 5) { /* Old 32-bit conversion version */ - if (num5 > 0 && num5 <= NUM_AFF_FLAGS) /* Ignore invalid values */ + if (num5 > 0 && num5 < NUM_AFF_FLAGS) /* Ignore invalid values */ SET_BIT_AR(af.bitvector, num5); } else { log("SYSERR: Invalid affects in pfile (%s), expecting 5 or 8 values", GET_NAME(ch)); diff --git a/src/spec_procs.c b/src/spec_procs.c index da9e7be..c852622 100644 --- a/src/spec_procs.c +++ b/src/spec_procs.c @@ -60,7 +60,7 @@ void sort_spells(void) static const char *how_good(int percent) { if (percent < 0) - return " error)"; + return " (error)"; if (percent == 0) return " (not learned)"; if (percent <= 10) diff --git a/src/structs.h b/src/structs.h index b784048..4954a1b 100644 --- a/src/structs.h +++ b/src/structs.h @@ -268,7 +268,7 @@ /* Affect bits: used in char_data.char_specials.saved.affected_by */ /* WARNING: In the world files, NEVER set the bits marked "R" ("Reserved") */ -#define AFF_DONTUSE 0 /**< DON'T USE! */ +#define AFF_DONTUSE 0 /**< DON'T USE! This allows 0 to mean "no bits set" in the database */ #define AFF_BLIND 1 /**< (R) Char is blind */ #define AFF_INVISIBLE 2 /**< Char is invisible */ #define AFF_DETECT_ALIGN 3 /**< Char is sensitive to align */ @@ -291,8 +291,8 @@ #define AFF_HIDE 20 /**< Char is hidden */ #define AFF_FREE 21 /**< Room for future expansion */ #define AFF_CHARM 22 /**< Char is charmed */ -/** Total number of affect flags not including the don't use flag. */ -#define NUM_AFF_FLAGS 22 +/** Total number of affect flags */ +#define NUM_AFF_FLAGS 23 /* Modes of connectedness: used by descriptor_data.state */ #define CON_PLAYING 0 /**< Playing - Nominal state */ diff --git a/src/utils.c b/src/utils.c index c138435..de4ca35 100644 --- a/src/utils.c +++ b/src/utils.c @@ -977,11 +977,6 @@ void column_list(struct char_data *ch, int num_cols, const char **list, int list /* Ensure that the number of columns is in the range 1-10 */ num_cols = MIN(MAX(num_cols,1), 10); - /* Work out the longest list item */ - for (i=0; i