# HG changeset patch # User Paul Aurich # Date 1246841154 0 # Node ID eff7db4db632925d335e275088b9867fb4ab1c48 # Parent c4196cd47602b519ac9e1ef859b3ae244360e5fe Various minor changes to jabber_presence_parse. No functionality changes. This will spit out a few more warnings and refuse to handle a presence with a non-standard type. There is no actual 'available' type, so don't bother checking for it in the last chunk in presence.c diff -r c4196cd47602 -r eff7db4db632 libpurple/protocols/jabber/buddy.c --- a/libpurple/protocols/jabber/buddy.c Sun Jul 05 23:55:56 2009 +0000 +++ b/libpurple/protocols/jabber/buddy.c Mon Jul 06 00:45:54 2009 +0000 @@ -1820,45 +1820,45 @@ return JABBER_BUDDY_STATE_UNKNOWN; } -JabberBuddyState jabber_buddy_show_get_state(const char *id) { - if(!id) - return JABBER_BUDDY_STATE_UNKNOWN; - if(!strcmp(id, "available")) - return JABBER_BUDDY_STATE_ONLINE; - if(!strcmp(id, "chat")) - return JABBER_BUDDY_STATE_CHAT; - if(!strcmp(id, "away")) - return JABBER_BUDDY_STATE_AWAY; - if(!strcmp(id, "xa")) - return JABBER_BUDDY_STATE_XA; - if(!strcmp(id, "dnd")) - return JABBER_BUDDY_STATE_DND; - if(!strcmp(id, "offline")) - return JABBER_BUDDY_STATE_UNAVAILABLE; - if(!strcmp(id, "error")) - return JABBER_BUDDY_STATE_ERROR; +const struct { + const char *name; + JabberBuddyState state; +} show_state_pairs[] = { + { "available", JABBER_BUDDY_STATE_ONLINE }, + { "chat", JABBER_BUDDY_STATE_CHAT }, + { "away", JABBER_BUDDY_STATE_AWAY }, + { "xa", JABBER_BUDDY_STATE_XA }, + { "dnd", JABBER_BUDDY_STATE_DND }, + { "offline", JABBER_BUDDY_STATE_UNAVAILABLE }, + { "error", JABBER_BUDDY_STATE_ERROR }, + { NULL, JABBER_BUDDY_STATE_UNKNOWN } +}; +JabberBuddyState jabber_buddy_show_get_state(const char *id) +{ + int i; + + g_return_val_if_fail(id != NULL, JABBER_BUDDY_STATE_UNKNOWN); + + for (i = 0; show_state_pairs[i].name; ++i) + if (g_str_equal(id, show_state_pairs[i].name)) + return show_state_pairs[i].state; + + purple_debug_warning("jabber", "Invalid value of presence " + "attribute: %s\n", id); return JABBER_BUDDY_STATE_UNKNOWN; } -const char *jabber_buddy_state_get_show(JabberBuddyState state) { - switch(state) { - case JABBER_BUDDY_STATE_CHAT: - return "chat"; - case JABBER_BUDDY_STATE_AWAY: - return "away"; - case JABBER_BUDDY_STATE_XA: - return "xa"; - case JABBER_BUDDY_STATE_DND: - return "dnd"; - case JABBER_BUDDY_STATE_ONLINE: - return "available"; - case JABBER_BUDDY_STATE_UNKNOWN: - case JABBER_BUDDY_STATE_ERROR: - return NULL; - case JABBER_BUDDY_STATE_UNAVAILABLE: - return "offline"; - } +const char * +jabber_buddy_state_get_show(JabberBuddyState state) +{ + int i; + + for (i = 0; show_state_pairs[i].name; ++i) + if (state == show_state_pairs[i].state) + return show_state_pairs[i].name; + +/* purple_debug_warning("jabber", "Unknown buddy state: %d\n", state); */ return NULL; } diff -r c4196cd47602 -r eff7db4db632 libpurple/protocols/jabber/presence.c --- a/libpurple/protocols/jabber/presence.c Sun Jul 05 23:55:56 2009 +0000 +++ b/libpurple/protocols/jabber/presence.c Mon Jul 06 00:45:54 2009 +0000 @@ -486,34 +486,57 @@ from = xmlnode_get_attrib(packet, "from"); type = xmlnode_get_attrib(packet, "type"); - if(!(jb = jabber_buddy_find(js, from, TRUE))) - return; + jb = jabber_buddy_find(js, from, TRUE); + g_return_if_fail(jb != NULL); signal_return = GPOINTER_TO_INT(purple_signal_emit_return_1(jabber_plugin, "jabber-receiving-presence", js->gc, type, from, packet)); if (signal_return) return; - if(!(jid = jabber_id_new(from))) + jid = jabber_id_new(from); + if (jid == NULL) { + purple_debug_error("jabber", "Ignoring presence with malformed 'from' " + "JID: %s\n", from); return; + } if(jb->error_msg) { g_free(jb->error_msg); jb->error_msg = NULL; } - if(type && !strcmp(type, "error")) { + if (type == NULL) { + xmlnode *show; + char *show_data = NULL; + + state = JABBER_BUDDY_STATE_ONLINE; + + show = xmlnode_get_child(packet, "show"); + if (show) { + show_data = xmlnode_get_data(show); + if (show_data) { + state = jabber_buddy_show_get_state(show_data); + g_free(show_data); + } else + purple_debug_warning("jabber", " present on presence, " + "but no contents!\n"); + } + } else if (g_str_equal(type, "error")) { char *msg = jabber_parse_error(js, packet, NULL); state = JABBER_BUDDY_STATE_ERROR; jb->error_msg = msg ? msg : g_strdup(_("Unknown Error in presence")); - } else if(type && !strcmp(type, "subscribe")) { + } else if (g_str_equal(type, "subscribe")) { struct _jabber_add_permit *jap = g_new0(struct _jabber_add_permit, 1); gboolean onlist = FALSE; - PurpleBuddy *buddy = purple_find_buddy(purple_connection_get_account(js->gc), from); + PurpleAccount *account; + PurpleBuddy *buddy; JabberBuddy *jb = NULL; xmlnode *nick; + account = purple_connection_get_account(js->gc); + buddy = purple_find_buddy(account, from); nick = xmlnode_get_child_with_namespace(packet, "nick", "http://jabber.org/protocol/nick"); if (nick) nickname = xmlnode_get_data(nick); @@ -528,16 +551,17 @@ jap->who = g_strdup(from); jap->js = js; - purple_account_request_authorization(purple_connection_get_account(js->gc), from, NULL, nickname, NULL, onlist, - authorize_add_cb, deny_add_cb, jap); + purple_account_request_authorization(account, from, NULL, nickname, + NULL, onlist, authorize_add_cb, deny_add_cb, jap); + g_free(nickname); jabber_id_free(jid); return; - } else if(type && !strcmp(type, "subscribed")) { + } else if (g_str_equal(type, "subscribed")) { /* we've been allowed to see their presence, but we don't care */ jabber_id_free(jid); return; - } else if(type && !strcmp(type, "unsubscribe")) { + } else if (g_str_equal(type, "unsubscribe")) { /* XXX I'm not sure this is the right way to handle this, it * might be better to add "unsubscribe" to the presence status * if lower down, but I'm not sure. */ @@ -547,13 +571,10 @@ jabber_id_free(jid); return; } else { - if((y = xmlnode_get_child(packet, "show"))) { - char *show = xmlnode_get_data(y); - state = jabber_buddy_show_get_state(show); - g_free(show); - } else { - state = JABBER_BUDDY_STATE_ONLINE; - } + purple_debug_warning("jabber", "Ignoring presence with invalid type " + "'%s'\n", type); + jabber_id_free(jid); + return; } @@ -688,7 +709,7 @@ } - if(type && !strcmp(type, "unavailable")) { + if (type && g_str_equal(type, "unavailable")) { gboolean nick_change = FALSE; gboolean kick = FALSE; gboolean is_our_resource = FALSE; /* Is the presence about us? */ @@ -887,8 +908,8 @@ } if(state == JABBER_BUDDY_STATE_ERROR || - (type && (!strcmp(type, "unavailable") || - !strcmp(type, "unsubscribed")))) { + (type && (g_str_equal(type, "unavailable") || + g_str_equal(type, "unsubscribed")))) { PurpleConversation *conv; jabber_buddy_remove_resource(jb, jid->resource); @@ -917,7 +938,7 @@ g_free(buddy_name); } - if (caps && (!type || g_str_equal(type, "available"))) { + if (caps && !type) { /* handle Entity Capabilities (XEP-0115) */ const char *node = xmlnode_get_attrib(caps, "node"); const char *ver = xmlnode_get_attrib(caps, "ver");