Re: [CODE] VisionMUD class_spells_index buffer overflows

From: Peter Ajamian (peter@pajamian.dhs.org)
Date: 08/07/00


Well, Netscape crashed on me when I was almost done replying before
(mutters), hopefully I'll be able to finish it this time...

Torgny Bjers wrote:

<snip>

> When it comes to about 240-250 characters in the string (STR I presume)

Actually it's str.  I know you capitalized it for emphasis, but C is
case sensative, and capitalizing variable names off hand is a VERY bad
habit to get into.

> it
> overflows or something and doesn't print anything else into the string, can
> any one help me out here?
>
Well, I'll look through and tell you what I can see...
>
> ---------------------------SNIP---------------------------------
> void class_spells_index(int chclass, char *str)
                                       ^^^^^^^^^

You're using a passed buffer to hold the output of ths function.  The
problem could easily be outside of the function and have to do with the
way the buffer is declared/allocated.

> {
>   int i, spellnum, num;
>   int n_spells, n_skills;

Hrmmm, the use of buf1 in this function could (possibly) be the problem
if buf1 is already in use by the calling function.  As a rule I only use
the global buffers in ACMDs and a few other places where I'm sure I
won't be stepping on nother functions usage of them or vice-versa.  To
find out if this is the problem and fix it in the same step simply
declare buf1 as a local which will isolate it from other functions as
follows...

char buf1[MAX_STRING_LENGTH];

>   *str = '\0';
>   sprinttype(chclass, pc_class_types, buf1);
>   sprintf(str,"&CSpells & Skills available for &G%ss&C.\r\n", buf1);
>   strcat(str,
> "&w-------------------------------------------------------------------------
> ----\r\n");
>   sprintf(str,"%s&WLevel          Spell/Skill   Name&w\r\n", str);
                 ^^                                          ^^^^^

This is bad (you can search the archives to find out why it has been
addressed several times), use...
strcat(str, "&WLevel          Spell/Skill   Name&w\r\n");
>
>   n_spells = 0;
>   n_skills = 0;
>   for (i = 1; i <= MAX_MORT_LEVEL; i++) {
>     sprintf(str,"%s&Y%2d&w   ", str, i);
                   ^^           ^^^^^

Again, this is bad, use...
sprintf(str + strlen(str), "&Y%2d&w   ", i);

>     num = 0;
>     for (spellnum = 1; spellnum < TOP_SPELLS; spellnum++) {
                      ^           ^

This will loop from 1 to TOP_SPELLS-1.  If you want to loop from 1 to
TOP_SPELLS use <= instead of <, if you want to loop from 0 to
TOP_SPELLS-1 (which is usually the case if you're using spellnum to
index an array) use spellnum = 0.

>       if (SINFO.min_level[chclass] == i) {
>         if (num >= 3) strcat(str, "\r\n     ");
>         if (spellnum >= 1 && spellnum <= MAX_SPELLS) {
              ^^^^^^^^^^^^^^^^^

This check is redundant, since spellnum starts at 1 and counts up it
will always be >=1 (see the above comment for changing the values that
spellnum loops through).

>           strcpy(buf1, "&m");
>           n_spells++;
>         } else if (spellnum > MAX_SPELLS  && spellnum <
                                ^^^^^^^^^^
> START_NON_PLAYER_SPELLS) {
  ^^^^^^^^^^^^^^^^^^^^^^^

So far I have seen TOP_SPELLS, MAX_SPELLS, and START_NON_PLAYER_SPELLS.
Double check these #defines to make ceartain they are correct.

>           strcpy(buf1, "&c");
>           n_skills++;
>         } else
>           strcpy(buf1, "&R");
>         sprintf(str, "%s%s%-22s", str, buf1, spells[spellnum]);
                        ^^        ^^^^^
Again this is bad, use
>         sprintf(str + strlen(str), "%s%-22s", buf1, spells[spellnum]);
>         num++;
>       }
>     }
>     strcat(str,"\r\n");
>
>   }
>   strcat(str, "\r\n");
>   sprintf(buf1, "&mSpells: &Y%d&w, &cSkills: &Y%d&w, &WTotal: &Y%d&w\r\n",
            ^^^^
> n_spells, n_skills, n_spells+n_skills);
>   strcat(str, buf1);
    ^^^^^^^^^^^^^^^^^^

It is a waste to copy all of this stuff twice, just use...
sprintf(str + strlen(str), "&mSpells: &Y%d&w, &cSkills: &Y%d&w, &WTotal:
&Y%d&w\r\n",         n_spells, n_skills, n_spells+n_skills);
>   return;
> }
> ---------------------------SNIP---------------------------------

Regards, Peter


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     |  http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html  |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 04/11/01 PDT