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