Hello again,

Thanks for the help.  I thought this looked rather strange and figured
changing buf to doors would be the best way to eliminate confusion for
me.  I wasn't sure if it was necessary, though.

I did change it from buf to doors, and it seems to be working well.  But
because the error was so sporadic, it may be a day or two before we see
the problem in action again.  I did uncomment the code and make it live
once more, so I'll keep you posted if I still don't see the
"nonenone" error within a week or so.

Thanks much,

Jimmy


On Sun, 3 Feb 2002, Dennis wrote:

> Hello,
> 
> First of all, you did a great job tracking this bug down  (yes, it is
> actually a bug).
> 
> Since you already know what the bug does, and you narrowed it down to
> the exact line causing the problem, I'm just going to try to explain
> WHY it's doing what it's doing (and tell you the easy fix).
> 
> I'll start by explaining strcat().  Strcat acts similar to:
> 
> char * strcat(char *dest, const char *src)
> {
>       int i = 0, j = 0;
> 
>       /* find the end of dest by finding the NUL character */
>       while ( dest[i] != '\0' )
>               i++;
> 
>       /* Copy src into dest */
>       while( src[j] != '\0' )
>       {
>               dest[i] = src[j];
>               i++;
>               j++;
>       }
> 
>       /* Append a NUL character onto dest */
>       dest[i] = '\0';
> 
>       return dest;
> }
> 
> The first while loop in my example strcat is what's causing the problem.
> It scans dest until it finds a NUL character.  But bust_a_prompt never
> puts a NUL character in buf, so only chance will decide if there is
> one there or not.  So this little loop runs along happily until it finds
> one out in memory somewhere.  (possibly somewhere in buf, possibly somewhere
> later).  Then it copies the string ("none" in this case) there, and appends
> a NUL character on the end.
> 
> The next time the bust_a_prompt code in question runs the strcat, it might
> do the same thing (assuming buf doesn't happen to have a NUL character
> hanging around this time).  But this time, the nul character it found
> last time was overwritten, so it keeps scanning until it finds the next
> one--the one strcat just put at the end.  So it copies "none" just after
> the last one.  So you end up with "nonenone".  The next time, it would
> add another one on, etc.
> 
> 
> Enough of the explanation of what's happening.  On to why buf is in the
> strcat.  This part I don't know for sure.  I'm just guessing what I think
> happened.
> 
> Some weird feeling came into me and possessed me to download the rom
> source and look up the code for do_exits.  When I started looking
> through the function, I noticed a great resemblance to the code I
> had been looking at in the %e case of bust_a_prompt.  The names were
> changed, but the structure was not.  Apparently whoever put the %e case
> in bust_a_prompt copied and pasted from do_exits.  The big difference in the
> two was that do_exits used buf to print everything into, bust_a_prompt
> did not.  Since bust_a_prompt already had a variable named buf, whoever
> copied the do_exits code into bust_a_prompt had to change the name.
> Instead of using buf2 like the rest of the cases (which would have
> been a cleaner solution, they added a new buffer to bust_a_prompt,
> named doors.  After using this buffer, they just copied it straight into
> buf2 (using an sprintf for some reason).  But, not all instances of "buf"
> got changed to "doors".  As you discovered, one of them never got changed
> to doors.
> 
> 
> At least this one has an easy fix.  The easiest way to fix it is to
> change 'strcat(buf,"none");' into 'strcat(doors,"none");'.  The
> cleaner way to fix it would be to remove the doors variable from
> bust_a_prompt, change all instances of doors to buf2, and remove the
> 'sprintf(buf2,"%s",doors);' line.
> 
> 
> I did a quick search on the web, and as far as I can tell, nobody's
> pointed out this bug before.  It looks like it probably exists on all
> rom muds at least back to 2.4b4 (that's the oldest souce I could find
> to look at).
> 
> 
> I hope I didn't bore you too much with this nice long letter.
> Once I started typing, it just didn't stop coming.
> 
> 
> In summary:  Using buf in the strcat line didn't make sense to you
> because it is wrong.  It should be doors (or buf2 if you want to just
> completely remove the unnecessary doors variable altogether).
> 
> 
> Hope this helps.
> Dennis Reed
> 
> 
> 
> On Sat, 2 Feb 2002, Anarchangel wrote:
> 
> >
> > Hello,
> >
> > My question is regarding bust_a_prompt and the %e (show exits in
> > prompt) option.
> >
> > I know it works properly, because it's stock and there have never been any
> > complaints about it on other muds (that I've seen).  However, we've run
> > into some problems with it over the years.  Just to give a little backup
> > information, any prior changes to the mud were not done by me, so I have
> > no way of checking anything changed recently.  It's been doing this for
> > quite some time.
> >
> > Particularly, I've noticed we have buf as MAX_STRING_LENGTH.  Further
> > down, there is a check to see if str is null, and if so it sets to buf to
> > a default prompt of <%ldhp %dm %dmv>.  This is all good and well, and I
> > understand this.
> >
> > However, when you check for case 'e' (again, to show exits in the
> > prompt) there's a strcat for "none" if no exits are found.  Why does it
> > use buf, exactly?  I realize it may be more efficient, since it does in
> > fact work.  This is confusing for me and I'm hoping one of you may have
> > some insight.
> >
> > The problem we're having involves this instance of the word none.  Every
> > now and then some things will start showing up like "nonenonenone".  It
> > could be titles, roomins, descriptions, sockets.. just about anything
> > relating to char_data.  It's not always "nonenonenone".  Sometimes it will
> > be simply "none", or perhaps "onenonenonenone"..  many possibilities,
> > really.  Other times, we'll crash and ch is 0x6e6f6e65, or maybe
> > 0x6f6e656e.  It's related to bust_a_prompt because I've determined that's
> > where the "none" is coming from.
> >
> > Like I said, I know the problem isn't within bust_a_prompt.  For the sake
> > of keeping these strange occurences from happening though, I've commented
> > it out until I've got the problem nailed down.
> >
> > If any of you could lend me some insight as to why buf is used as it is,
> > that may help me track the problem down.  Or better yet, why nonenone is
> > happening in the first place.
> >
> > I apologize if my description isn't very clear, but I'll gladly send more
> > information if need be.  I don't have a gdb readout because that section
> > of the code is commented out, and the problem is no longer happening.  I
> > suspect it will simply manifest itself elsewhere, though.
> >
> > Thanks for your time,
> >
> > Jimmy
> >
> >
> >
> >
> >
> 
> 


Reply via email to