# HG changeset patch # User tomkiewicz@cpw.pidgin.im # Date 1337968973 0 # Node ID 9686216828f97ebd09b2da9eadc640f9a989bc75 # Parent 3b1070cb4f2940d64b14614ba8a2832a00cdecc7# Parent b37309823450fdd504d966bb80848a0cca3593de propagate from branch 'im.pidgin.soc.2012.gg' (head 7e7ded95fce2925f90c076c274edad16084b5032) to branch 'im.pidgin.pidgin' (head 79a577d0889f9db570dd39f03efd0605e9aba218) diff -r b37309823450 -r 9686216828f9 ChangeLog --- a/ChangeLog Sun May 20 19:27:17 2012 +0000 +++ b/ChangeLog Fri May 25 18:02:53 2012 +0000 @@ -39,6 +39,7 @@ to the core (and UIs) as incoming messages (Thijs Alkemade). (#14529) * Support file transfers up to ~9 EiB. + * Invalid user moods can no longer be sent to the server. Plugins: * The Voice/Video Settings plugin supports using the sndio GStreamer diff -r b37309823450 -r 9686216828f9 libpurple/protocols/jabber/jabber.c --- a/libpurple/protocols/jabber/jabber.c Sun May 20 19:27:17 2012 +0000 +++ b/libpurple/protocols/jabber/jabber.c Fri May 25 18:02:53 2012 +0000 @@ -3575,16 +3575,32 @@ JabberStream *js = purple_connection_get_protocol_data(purple_account_get_connection(account)); if (js->pep) { - /* if no argument was given, unset mood */ + gboolean ret; + if (!args || !args[0]) { - jabber_mood_set(js, NULL, NULL); - } else if (!args[1]) { - jabber_mood_set(js, args[0], NULL); + /* No arguments; unset mood */ + ret = jabber_mood_set(js, NULL, NULL); } else { - jabber_mood_set(js, args[0], args[1]); + /* At least one argument. Relying on the list of arguments + * being NULL-terminated. + */ + ret = jabber_mood_set(js, args[0], args[1]); + if (!ret) { + /* Let's try again */ + char *tmp = g_strjoin(" ", args[0], args[1], NULL); + ret = jabber_mood_set(js, "undefined", tmp); + g_free(tmp); + } } - return PURPLE_CMD_RET_OK; + if (ret) { + return PURPLE_CMD_RET_OK; + } else { + purple_conversation_write(conv, NULL, + _("Failed to specify mood"), + PURPLE_MESSAGE_ERROR, time(NULL)); + return PURPLE_CMD_RET_FAILED; + } } else { /* account does not support PEP, can't set a mood */ purple_conversation_write(conv, NULL, @@ -3713,7 +3729,7 @@ PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_PRPL_ONLY | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", jabber_cmd_mood, - _("mood: Set current user mood"), NULL); + _("mood <mood> [text]: Set current user mood"), NULL); commands = g_slist_prepend(commands, GUINT_TO_POINTER(id)); g_hash_table_insert(jabber_cmds, plugin, commands); diff -r b37309823450 -r 9686216828f9 libpurple/protocols/jabber/usermood.c --- a/libpurple/protocols/jabber/usermood.c Sun May 20 19:27:17 2012 +0000 +++ b/libpurple/protocols/jabber/usermood.c Fri May 25 18:02:53 2012 +0000 @@ -115,10 +115,26 @@ {"undefined", N_("Undefined"), NULL}, {"weak", N_("Weak"), NULL}, {"worried", N_("Worried"), NULL}, - /* Mark the last record. */ + /* Mar last record. */ {NULL, NULL, NULL} }; +static const PurpleMood* +find_mood_by_name(const gchar *name) +{ + int i; + + g_return_val_if_fail(name && *name, NULL); + + for (i = 0; moods[i].mood != NULL; ++i) { + if (g_str_equal(name, moods[i].mood)) { + return &moods[i]; + } + } + + return NULL; +} + static void jabber_mood_cb(JabberStream *js, const char *from, xmlnode *items) { /* it doesn't make sense to have more than one item here, so let's just pick the first one */ xmlnode *item = xmlnode_get_child(items, "item"); @@ -139,15 +155,13 @@ if (!moodtext) /* only pick the first one */ moodtext = xmlnode_get_data(moodinfo); } else { - int i; - for (i = 0; moods[i].mood; ++i) { - /* verify that the mood is known (valid) */ - if (!strcmp(moodinfo->name, moods[i].mood)) { - newmood = moods[i].mood; - break; - } - } + const PurpleMood *target_mood; + + /* verify that the mood is known (valid) */ + target_mood = find_mood_by_name(moodinfo->name); + newmood = target_mood ? target_mood->mood : NULL; } + if (newmood != NULL && moodtext != NULL) break; } @@ -170,26 +184,41 @@ jabber_pep_register_handler("http://jabber.org/protocol/mood", jabber_mood_cb); } -void jabber_mood_set(JabberStream *js, const char *mood, const char *text) { +gboolean +jabber_mood_set(JabberStream *js, const char *mood, const char *text) +{ + const PurpleMood *target_mood = NULL; xmlnode *publish, *moodnode; + if (mood && *mood) { + target_mood = find_mood_by_name(mood); + /* Mood specified, but is invalid -- + * fail so that the command can handle this. + */ + if (!target_mood) + return FALSE; + } + publish = xmlnode_new("publish"); xmlnode_set_attrib(publish,"node","http://jabber.org/protocol/mood"); moodnode = xmlnode_new_child(xmlnode_new_child(publish, "item"), "mood"); xmlnode_set_namespace(moodnode, "http://jabber.org/protocol/mood"); - if (mood && *mood) { - /* if mood is NULL, set an empty mood node, meaning: unset mood */ + + if (target_mood) { + /* If target_mood is not NULL, then + * target_mood->mood == mood, and is a valid element name. + */ xmlnode_new_child(moodnode, mood); - } - if (text && *text) { - xmlnode *textnode = xmlnode_new_child(moodnode, "text"); - xmlnode_insert_data(textnode, text, -1); + /* Only set text when setting a mood */ + if (text && *text) { + xmlnode *textnode = xmlnode_new_child(moodnode, "text"); + xmlnode_insert_data(textnode, text, -1); + } } jabber_pep_publish(js, publish); - /* publish is freed by jabber_pep_publish -> jabber_iq_send -> jabber_iq_free - (yay for well-defined memory management rules) */ + return TRUE; } PurpleMood *jabber_get_moods(PurpleAccount *account) diff -r b37309823450 -r 9686216828f9 libpurple/protocols/jabber/usermood.h --- a/libpurple/protocols/jabber/usermood.h Sun May 20 19:27:17 2012 +0000 +++ b/libpurple/protocols/jabber/usermood.h Fri May 25 18:02:53 2012 +0000 @@ -30,9 +30,20 @@ void jabber_mood_init(void); -void jabber_mood_set(JabberStream *js, - const char *mood, /* must be one of the valid strings defined in the XEP */ - const char *text /* might be NULL */); +/** + * Sets / unsets the mood for the specified account. The mood passed in + * must either be NULL, "", or one of the moods returned by + * jabber_get_moods(). + * + * @param js The JabberStream object. + * @param mood The mood to set, NULL, or "" + * @param text Optional text that goes along with a mood. Only used when + * setting a mood (not when unsetting a mood). + * + * @return FALSE if an invalid mood was specified, or TRUE otherwise. + */ +gboolean +jabber_mood_set(JabberStream *js, const char *mood, const char *text); PurpleMood *jabber_get_moods(PurpleAccount *account); diff -r b37309823450 -r 9686216828f9 libpurple/stun.c --- a/libpurple/stun.c Sun May 20 19:27:17 2012 +0000 +++ b/libpurple/stun.c Fri May 25 18:02:53 2012 +0000 @@ -174,6 +174,8 @@ struct ifreq *ifr; struct sockaddr_in *sinptr; + memset(&in, 0, sizeof(in)); + len = recv(source, buffer, sizeof(buffer) - 1, 0); if (!len) { purple_debug_warning("stun", "unable to read stun response\n");