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
This commit is contained in:
Thomas Arp 2020-02-26 00:39:29 +01:00 committed by GitHub
parent 7f0acefcb4
commit eb650c2811
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 17 additions and 21 deletions

View file

@ -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; i<NUM_AFF_FLAGS; i++) {
for (i=1; i<NUM_AFF_FLAGS; i++) {
if (IS_SET_AR(aff->bitvector, i)) {
send_to_char(ch, "sets %s, ", affected_bits[i]);
}

View file

@ -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

View file

@ -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; j<NUM_AFF_FLAGS; j++) {
for (j=1; j<NUM_AFF_FLAGS; j++) {
if (IS_SET_AR(af[i].bitvector, j) && AFF_FLAGGED(victim, j)) {
send_to_char(ch, "%s", CONFIG_NOEFFECT);
return;

View file

@ -396,8 +396,8 @@ static void medit_disp_aff_flags(struct descriptor_data *d)
get_char_colors(d->character);
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. */

View file

@ -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);

View file

@ -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));

View file

@ -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)

View file

@ -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 */

View file

@ -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<list_length; i++)
if (max_len < strlen(list[i]))
max_len = strlen(list[i]);
/* Calculate the width of each column */
if (IS_NPC(ch)) col_width = 80 / num_cols;
else col_width = (GET_SCREEN_WIDTH(ch)) / num_cols;