07 Aug, 2009, Kayle wrote in the 1st comment:
Votes: 0
So, I'm playing around with various snippets for my Star Wars Side-project to kinda get away from Elysium for a few days, and I come across this interesting gem.

Quote
[Force]: 2700/2700 [Align]: 0
[Health]: 500/500 [Move]: 1000/1000 [Credits]: 0 > semote Testing.
Testing. [Kayle].

Testing.
Ok.


K, So lemme explain that. I use semote (code below) with an argument of Testing. It then changes my prompt to Testing. Along with my Bio, Description, Disguise, Short Description, and Long Description. I'm playing with this on a stock SWFotEFUSS 1.whatever the current one on SmaugMuds is. And it's mind boggling. Anyway, here's the code for semote, courtesy of Noplex, with some modifications to get g++4.4 to stfu.

/* Summary: Allows for three different types of emoting utilizing
* the ACT function's meta-character, the character's name, or by
* appending the name at the end in brackets.
* License: http://creativecommons.org/licenses/by-n...
* Author: John "Noplex" Bellone (j.bellone@flipsidesoftware.com)
*/
CMDF( do_semote )
{
if( IS_NPC( ch ) )
{
send_to_char( "Huh?\r\n", ch );
return;
}

if( argument[0] == '\0' )
{
pager_printf( ch, "&YSyntax: semote […]\r\nSyntax: semote [..$n..]\r\nSyntax: semote [..%s..]&D\r\n", ch->name );
return;
}

/* cleaning up the string a bit */
//Redone to shut g++4.4 up. - Kayle
char *buf = STRALLOC( "" );
const char *plast;
for( plast = argument; *plast != '\0'; plast++ )
;

strcpy( buf, argument );
if( isalpha( plast[-1] ) )
strcat( buf, "." );

/* utilizing the ACT $n meta-character */
if( strstr( buf, "$n" ) )
{
act( AT_SOCIAL, buf, ch, NULL, NULL, TO_ROOM );
act( AT_SOCIAL, buf, ch, NULL, NULL, TO_CHAR );
return;
}
/* utilizing the character's name inside the emote */
else if( strstr( buf, ch->name ) )
{
/* Only need to poll the descriptors because there is no point in sending
* area echos to people that are switched or controlling NPCs */
DESCRIPTOR_DATA* d;
for( d = first_descriptor; d; d = d->next )
if( d->character && d->character->in_room == ch->in_room )
{
set_char_color( AT_SOCIAL, d->character );
ch_printf( d->character, "%s &C[&c%s&C].\r\n", buf, PERS( ch, d->character ) );
}
return;
}

/* the name appending to the end of the string in brackets */
DESCRIPTOR_DATA* d;
for( d = first_descriptor; d; d = d->next )
if( d->character && d->character->in_room == ch->in_room )
{
set_char_color( AT_SOCIAL, d->character );
ch_printf( d->character, "%s &C[&c%s&C].\r\n", buf, PERS( ch, d->character ) );
}
}


Does anyone see anything at all in there that could be remotely possible for this? Because… I don't. I just.. I'm at a loss. It's frustrating, and at the same time funny as hell. If there's anything else anyone needs just lemme know.
07 Aug, 2009, David Haley wrote in the 2nd comment:
Votes: 0
Quote
char *buf = STRALLOC( "" );
const char *plast;
for( plast = argument; *plast != '\0'; plast++ )
;

strcpy( buf, argument );
if( isalpha( plast[-1] ) )
strcat( buf, "." );

This is stomping all over all kinds of things it shouldn't be stomping over. Recall that stralloc gives you a pointer to a shared string: you really, really shouldn't be writing to that buffer. The stralloc return value should be a const char* for this reason.

Anyhow, if you want an empty string, you should just create a buffer like char buf[123], not allocate a string on the heap (note also that you have a memory leak because you don't free the string you allocated).
07 Aug, 2009, David Haley wrote in the 3rd comment:
Votes: 0
To elaborate somewhat and explain why other strings were changing, it's all but certain that the shared string for the empty string was being modified, so any other occurrence of the empty string (using the shared string mechanism) would also be modified.
07 Aug, 2009, Kayle wrote in the 4th comment:
Votes: 0
Yep, replaced
char *buf = STRALLOC( "" );
const char *plast;
for( plast = argument; *plast != '\0'; plast++ )
;

strcpy( buf, argument );
if( isalpha( plast[-1] ) )
strcat( buf, "." );


with
char buf[MSL];
const char *plast;
for( plast = argument; *plast != '\0'; plast++ )
;

strcpy( buf, argument );
if( isalpha( plast[-1] ) )
strcat( buf, "." );


And now it works without flaw. This just reaffirms my hatred of c-style strings. It's too bad swapping SWFotE over to use std::string would be a massive pain in the ass.
07 Aug, 2009, Guest wrote in the 5th comment:
Votes: 0
And this after I pointed out other instances where you shouldn't be doing that the other night. :P
08 Aug, 2009, Kayle wrote in the 6th comment:
Votes: 0
Hmm. Was this the same thing? =/
08 Aug, 2009, Guest wrote in the 7th comment:
Votes: 0
Same kind of thing - not using strcpy on a STRALLOC'd string. Or a str_dup'd one for that matter.
0.0/7