pidgin: 79a577d0: jabber: Validate user moods, and make th...
darkrain42 at pidgin.im
darkrain42 at pidgin.im
Wed May 23 01:18:34 EDT 2012
----------------------------------------------------------------------
Revision: 79a577d0889f9db570dd39f03efd0605e9aba218
Parent: c783586116efc784f256230deebc63785a85afde
Author: darkrain42 at pidgin.im
Date: 05/23/12 01:01:14
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/79a577d0889f9db570dd39f03efd0605e9aba218
Changelog:
jabber: Validate user moods, and make the /mood cmd behave flexibly.
A user in Pidgin running "/mood ?" or "/mood -" would result in invalid
XML being sent to the server (similar to #14342, except '<-/>' or '<?/>').
Prevent this by ensuring the user is specifying something from the list.
The /mood command will also now try to treat its entire arguments as
a single string, and set that as the mood -- I figure this is what a
user would expect?
Changes against parent c783586116efc784f256230deebc63785a85afde
patched ChangeLog
patched libpurple/protocols/jabber/jabber.c
patched libpurple/protocols/jabber/usermood.c
patched libpurple/protocols/jabber/usermood.h
-------------- next part --------------
============================================================
--- ChangeLog 5a4561bb8357c230985a73f1d99098cd6c3e0585
+++ ChangeLog 1f0fbe0b557c962686d9606bf38142e72608555a
@@ -39,6 +39,7 @@ version 3.0.0 (??/??/????):
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
============================================================
--- libpurple/protocols/jabber/jabber.c 6af9f2854e3229d956ff808b18167eb71dfd48fc
+++ libpurple/protocols/jabber/jabber.c 0f5984a6923dac0c50285e8cc76270ea16e051e2
@@ -3575,16 +3575,32 @@ jabber_cmd_mood(PurpleConversation *conv
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 @@ static void jabber_register_commands(Pur
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);
============================================================
--- libpurple/protocols/jabber/usermood.c 892cc11f7a3655233ee93f88e22ab9f251880681
+++ libpurple/protocols/jabber/usermood.c 4204a3409450c86ca68e9af66e5db655582da49c
@@ -115,10 +115,26 @@ static PurpleMood moods[] = {
{"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 @@ static void jabber_mood_cb(JabberStream
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 @@ void jabber_mood_init(void) {
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)
============================================================
--- libpurple/protocols/jabber/usermood.h d20b021d8b2a06f7dc870613c8c8ed2e5d04361a
+++ libpurple/protocols/jabber/usermood.h 7f4ea0b588473aca197075dc22bceb66a3d366d3
@@ -30,9 +30,20 @@ void jabber_mood_init(void);
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);
More information about the Commits
mailing list