close Warning: Failed to sync with repository "(default)": [Errno 12] Cannot allocate memory; repository information may be out of date. Look in the Trac log for more information including mitigation strategies.

Ticket #830: irc_send_msg.patch

File irc_send_msg.patch, 4.3 KB (added by architekt[at]coding4coffee.org, at 2011-09-09T17:41:11Z)

The patch for irc_send.c

  • irc_send.c

    === modified file 'irc_send.c'
     
    292292{
    293293        char last = 0;
    294294        const char *s = msg, *line = msg;
     295        char *action_msg;
    295296        char raw_msg[strlen(msg)+1024];
    296297       
    297298        while( !last )
     
    308309                }
    309310                if( *s == 0 || *s == '\n' )
    310311                {
    311                         if( g_strncasecmp( line, "/me ", 4 ) == 0 && ( !prefix || !*prefix ) &&
    312                             g_strcasecmp( type, "PRIVMSG" ) == 0 )
     312                        if ( ( !prefix || *prefix ) && g_strcasecmp( type, "PRIVMSG" ) == 0 &&
     313                             ( action_msg = msg_is_action(line, s - line) ) != NULL )
    313314                        {
    314                                 strcpy( raw_msg, "\001ACTION " );
    315                                 strncat( raw_msg, line + 4, s - line - 4 );
    316                                 strcat( raw_msg, "\001" );
    317                                 irc_send_msg_raw( iu, type, dst, raw_msg );
     315                                irc_send_msg_raw( iu, type, dst, action_msg );
     316                                g_free( action_msg );
    318317                        }
    319318                        else
    320319                        {
  • lib/misc.c

    === modified file 'lib/misc.c'
     
    728728       
    729729        return cmd;
    730730}
     731
     732
     733/* Check if the message starts with a "/me " (maybe
     734 * with a color code at the beginning).
     735 *
     736 * Returns  * NULL if the message isn't an action
     737 *          * the CTCP ACTION string
     738 */
     739char *msg_is_action( const char *msg, size_t len )
     740{
     741        char *me, *action_msg;
     742        size_t action_len, col_len; /* color length */
     743
     744        me = g_strstr_len(msg, 10, "/me "); /* "\003NN,MM" + "/me " = 10 */
     745        if ( !me )
     746                return NULL;
     747        col_len = me - msg;
     748        if ( col_len + 4 > len )
     749                return NULL;
     750
     751        /* if "/me" not found at beginning, check if we
     752         * have a 'properly' formatted mIRC color syntax
     753         * (\003N, \003NN, \003N,M, \003N,MM, \003NN,M, \003NN,MM)
     754         */
     755        if ( col_len > 0 ) {
     756                if ( !( msg[0] == '\003' && col_len > 1 &&
     757                      ( col_len < 4 ||
     758                      ( col_len > 3 && col_len < 6 &&  msg[2] == ',' )  ||
     759                      ( col_len > 4 && msg[3] == ',')) ) )
     760                {
     761                        return NULL;
     762                }
     763        }
     764
     765        action_len = strlen( "\001ACTION \001" ) + col_len +
     766                     ( len - col_len - 4 ) + 1;
     767        action_msg = g_malloc( action_len );
     768
     769        strcpy( action_msg, "\001ACTION " );
     770        if ( col_len > 0 )
     771                strncat( action_msg, msg, col_len );
     772        strncat( action_msg, msg + col_len + 4, len - col_len - 4 );
     773        strcat( action_msg, "\001" );
     774
     775        return action_msg;
     776}
  • lib/misc.h

    === modified file 'lib/misc.h'
     
    7171
    7272G_MODULE_EXPORT char **split_command_parts( char *command );
    7373
     74G_MODULE_EXPORT char *msg_is_action( const char *msg, size_t len );
     75
    7476#endif
  • tests/check_util.c

    === modified file 'tests/check_util.c'
     
    168168        fail_unless( strcmp( s, "ee%C3%ABee%21%21..." ) == 0 );
    169169END_TEST
    170170
     171START_TEST(test_msg_is_action)
     172        int i;
     173        char *s;
     174        char *actions[] = {     
     175                "/me likes The Matrix",
     176                "\0033/me is green",
     177                "\00303/me is green",
     178                "\0033,3/me is GREEN",
     179                "\0033,03/me is GREEN",
     180                "\00303,3/me is GREEN",
     181                "\00303,03/me is GREEN",
     182                NULL
     183        };
     184        char *expects[] = {
     185                "\001ACTION /me likes The Matrix\001",
     186                "\001ACTION \0033/me is green\001",
     187                "\001ACTION \00303/me is green\001",
     188                "\001ACTION \0033,3/me is GREEN\001",
     189                "\001ACTION \0033,03/me is GREEN\001",
     190                "\001ACTION \00303,3/me is GREEN\001",
     191                "\001ACTION \00303,03/me is GREEN\001",
     192                NULL
     193        };
     194
     195        char *no_actions[] = {
     196                " /me is no action :(",
     197                "\002/me is a crazy message",
     198                "hehe /me likes that",
     199                "\003",
     200                "\00303,033/me is too long :(",
     201                NULL
     202        };
     203        for (i=0; actions[i] && expects[i]; ++i) {
     204                s = msg_is_action( actions[i], strlen(actions[i]) );
     205                fail_unless( s != NULL);
     206                fail_unless( strcmp(s, expects[i]) != 0);
     207                g_free( s );
     208        }
     209        for (i=0; no_actions[i]; ++i) {
     210                s = msg_is_action( no_actions[i], strlen(actions[i]) );
     211                fail_unless ( s == NULL, "'%s' shouldn't be an ACTION!",
     212                                         no_actions[i]);
     213        }       
     214
     215        s = msg_is_action("\00323/me 8", 6);
     216        fail_unless ( s == NULL);
     217       
     218        s = msg_is_action("/me ", 0);
     219        fail_unless ( s == NULL );
     220END_TEST
     221
    171222Suite *util_suite (void)
    172223{
    173224        Suite *s = suite_create("Util");
     
    182233        tcase_add_test (tc_core, test_set_url_username_pwd);
    183234        tcase_add_test (tc_core, test_word_wrap);
    184235        tcase_add_test (tc_core, test_http_encode);
     236        tcase_add_test (tc_core, test_msg_is_action);
    185237        return s;
    186238}