Mercurial > pidgin
changeset 29830:38926d6e5ae1
propagate from branch 'im.pidgin.pidgin' (head 83880c1513774ae8550442dfe002355056d39021)
to branch 'im.pidgin.cpw.malu.ft_thumbnails' (head ce7131f6a58510cde83d0cb3945eca0795e1e2aa)
author | Marcus Lundblad <ml@update.uu.se> |
---|---|
date | Wed, 24 Mar 2010 19:56:07 +0000 |
parents | 33a4d72232a7 (diff) 90dbc46a771f (current diff) |
children | 816041183dda |
files | libpurple/protocols/jabber/data.c libpurple/protocols/jabber/data.h libpurple/protocols/jabber/message.c |
diffstat | 7 files changed, 153 insertions(+), 143 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Mar 22 22:26:14 2010 +0000 +++ b/ChangeLog Wed Mar 24 19:56:07 2010 +0000 @@ -55,7 +55,9 @@ rjoly for testing) * When sending data using in-band-bytestreams, interpret the block-size attribute as the size of the BASE64-encoded representation of the data. - * Validate the hash on incoming BoB data objects (for custom smileys etc.). + * Validate the hash on incoming BoB data objects (for custom smileys etc.), + cache based per JID when the CID is not a valid hash (as specified by the + BoB XEP). Yahoo: * Attempt to better handle transparent proxies interfering with HTTP-based
--- a/doc/gtkimhtml-signals.dox Mon Mar 22 22:26:14 2010 +0000 +++ b/doc/gtkimhtml-signals.dox Wed Mar 24 19:56:07 2010 +0000 @@ -6,7 +6,7 @@ @signal format_function_clear @signal format_function_toggle @signal format_function_update - @paste + @signal paste @endsignals @see gtkimhtml.h
--- a/finch/libgnt/gntbox.c Mon Mar 22 22:26:14 2010 +0000 +++ b/finch/libgnt/gntbox.c Wed Mar 24 19:56:07 2010 +0000 @@ -27,6 +27,9 @@ #include <string.h> +#define PROP_LAST_RESIZE_S "last-resize" +#define PROP_SIZE_QUEUED_S "size-queued" + enum { PROP_0, @@ -194,7 +197,7 @@ GntBox *box = GNT_BOX(widget); GList *iter; int maxw = 0, maxh = 0; - + g_list_foreach(box->list, (GFunc)gnt_widget_size_request, NULL); for (iter = box->list; iter; iter = iter->next) @@ -398,6 +401,7 @@ GList *iter; GntBox *box = GNT_BOX(widget); int wchange, hchange; + GntWidget *child, *last; if (!box->list) return TRUE; @@ -406,67 +410,59 @@ hchange = widget->priv.height - height; if (wchange == 0 && hchange == 0) - return TRUE; /* Quit playing games */ + return TRUE; /* Quit playing games with my size */ - /* XXX: Right now, I am trying to just apply all the changes to - * just one widget. It should be possible to distribute the - * changes to all the widgets in the box. */ - for (iter = box->list; iter; iter = iter->next) - { + child = NULL; + last = g_object_get_data(G_OBJECT(box), PROP_LAST_RESIZE_S); + + /* First, make sure all the widgets will fit into the box after resizing. */ + for (iter = box->list; iter; iter = iter->next) { GntWidget *wid = iter->data; int w, h; gnt_widget_get_size(wid, &w, &h); - if (gnt_widget_confirm_size(wid, w - wchange, h - hchange)) - { - GList *i; - - for (i = box->list; i; i = i->next) - { - int tw, th; - if (i == iter) continue; - gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th); - if (box->vertical) - { - if (!gnt_widget_confirm_size(i->data, tw - wchange, th)) { - /* If we are decreasing the size and the widget is going - * to be too large to fit into the box, then do not allow - * resizing. */ - if (wchange > 0 && tw >= widget->priv.width) - return FALSE; - } - } - else - { - if (!gnt_widget_confirm_size(i->data, tw, th - hchange)) { - if (hchange > 0 && th >= widget->priv.height) - return FALSE; - return FALSE; - } - } - } -#if 0 - gnt_widget_set_size(wid, w - wchange, h - hchange); - if (box->vertical) - hchange = 0; - else - wchange = 0; - - for (i = box->list; i; i = i->next) - { - int tw, th; - if (i == iter) continue; - gnt_widget_get_size(GNT_WIDGET(i->data), &tw, &th); - gnt_widget_set_size(i->data, tw - wchange, th - hchange); - } -#endif - g_object_set_data(G_OBJECT(box), "size-queued", wid); - return TRUE; + if (wid != last && !child && gnt_widget_confirm_size(wid, w - wchange, h - hchange)) { + child = wid; + break; } } - return FALSE; + if (!child && (child = last)) { + int w, h; + gnt_widget_get_size(child, &w, &h); + if (!gnt_widget_confirm_size(child, w - wchange, h - hchange)) + child = NULL; + } + + g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, child); + + if (child) { + for (iter = box->list; iter; iter = iter->next) { + GntWidget *wid = iter->data; + int w, h; + + gnt_widget_get_size(wid, &w, &h); + if (box->vertical) { + /* For a vertical box, if we are changing the width, make sure the widgets + * in the box will fit after resizing the width. */ + if (wchange > 0 && + w >= child->priv.width && + !gnt_widget_confirm_size(wid, w - wchange, h)) + return FALSE; + } else { + /* If we are changing the height, make sure the widgets in the box fit after + * the resize. */ + if (hchange > 0 && + h >= child->priv.height && + !gnt_widget_confirm_size(wid, w, h - hchange)) + return FALSE; + } + + } + } + + return (child != NULL); } static void @@ -477,16 +473,16 @@ GntBox *box = GNT_BOX(widget); GntWidget *wid; int tw, th; - + wchange = widget->priv.width - oldw; hchange = widget->priv.height - oldh; - - wid = g_object_get_data(G_OBJECT(box), "size-queued"); - if (wid) - { + + wid = g_object_get_data(G_OBJECT(box), PROP_SIZE_QUEUED_S); + if (wid) { gnt_widget_get_size(wid, &tw, &th); gnt_widget_set_size(wid, tw + wchange, th + hchange); - g_object_set_data(G_OBJECT(box), "size-queued", NULL); + g_object_set_data(G_OBJECT(box), PROP_SIZE_QUEUED_S, NULL); + g_object_set_data(G_OBJECT(box), PROP_LAST_RESIZE_S, wid); } if (box->vertical)
--- a/libpurple/protocols/jabber/data.c Mon Mar 22 22:26:14 2010 +0000 +++ b/libpurple/protocols/jabber/data.c Wed Mar 24 19:56:07 2010 +0000 @@ -55,58 +55,6 @@ return data; } - -static gboolean -jabber_data_has_valid_hash(const JabberData *data) -{ - const gchar *cid = jabber_data_get_cid(data); - gchar **cid_parts = g_strsplit(cid, "@", -1); - gchar **iter; - int num_parts = 0; - - purple_debug_info("jabber", "validating BoB hash %s\n", cid); - - for (iter = cid_parts; *iter != NULL ; iter++) { - num_parts++; - } - - if (num_parts == 2 && purple_strequal(cid_parts[1], "bob.xmpp.org")) { - gchar **sub_parts = g_strsplit(cid_parts[0], "+", -1); - - num_parts = 0; - for (iter = sub_parts ; *iter != NULL ; iter++) { - num_parts++; - } - - if (num_parts == 2) { - const gchar *hash_algo = sub_parts[0]; - const gchar *hash_value = sub_parts[1]; - gchar *digest = - jabber_calculate_data_hash(jabber_data_get_data(data), - jabber_data_get_size(data), hash_algo); - - purple_debug_info("jabber", "BoB expecting hash: %s\n", digest); - - if (digest) { - gboolean result = purple_strequal(digest, hash_value); - - if (!result) { - purple_debug_error("jabber", "invalid BoB hash\n"); - } - g_free(digest); - return result; - } else { - purple_debug_info("jabber", "unknown BoB hash algo\n"); - return FALSE; - } - } else { - return TRUE; - } - } else { - return TRUE; - } -} - static void jabber_data_delete(gpointer cbdata) { @@ -160,11 +108,6 @@ data->cid = g_strdup(cid); data->type = g_strdup(type); - if (!jabber_data_has_valid_hash(data)) { - jabber_data_delete(data); - return NULL; - } - return data; } @@ -240,6 +183,57 @@ return tag; } +static gboolean +jabber_data_has_valid_hash(const JabberData *data) +{ + const gchar *cid = jabber_data_get_cid(data); + gchar **cid_parts = g_strsplit(cid, "@", -1); + gchar **iter; + int num_parts = 0; + + purple_debug_info("jabber", "validating BoB hash %s\n", cid); + + for (iter = cid_parts; *iter != NULL ; iter++) { + num_parts++; + } + + if (num_parts == 2 && purple_strequal(cid_parts[1], "bob.xmpp.org")) { + gchar **sub_parts = g_strsplit(cid_parts[0], "+", -1); + + num_parts = 0; + for (iter = sub_parts ; *iter != NULL ; iter++) { + num_parts++; + } + + if (num_parts == 2) { + const gchar *hash_algo = sub_parts[0]; + const gchar *hash_value = sub_parts[1]; + gchar *digest = + jabber_calculate_data_hash(jabber_data_get_data(data), + jabber_data_get_size(data), hash_algo); + + if (digest) { + gboolean result = purple_strequal(digest, hash_value); + + purple_debug_info("jabber", "BoB expecting hash: %s\n", digest); + + if (!result) { + purple_debug_error("jabber", "invalid BoB hash\n"); + } + g_free(digest); + return result; + } else { + purple_debug_info("jabber", "unknown BoB hash algo\n"); + return FALSE; + } + } else { + return FALSE; + } + } else { + return FALSE; + } +} + typedef struct { gpointer userdata; @@ -265,17 +259,10 @@ if (data_element && type == JABBER_IQ_RESULT) { JabberData *data = jabber_data_create_from_xml(data_element); - if (data) { - if (!ephemeral) { - jabber_data_associate_remote(data); - } - cb(data, alt, userdata); - } else { - /* could not validate hash when creating data from XML */ - purple_debug_info("jabber", - "hash validation failed on requested BoB object\n"); - cb(NULL, alt, userdata); + if (!ephemeral) { + jabber_data_associate_remote(js, from, data); } + cb(data, alt, userdata); } else if (item_not_found) { purple_debug_info("jabber", "Responder didn't recognize requested data\n"); @@ -323,11 +310,24 @@ } const JabberData * -jabber_data_find_remote_by_cid(const gchar *cid) +jabber_data_find_remote_by_cid(JabberStream *js, const gchar *who, + const gchar *cid) { + const JabberData *data = g_hash_table_lookup(remote_data_by_cid, cid); + purple_debug_info("jabber", "lookup remote smiley with cid = %s\n", cid); purple_debug_info("jabber", "lookup remote data object with cid = %s\n", cid); - return g_hash_table_lookup(remote_data_by_cid, cid); + if (data == NULL) { + gchar *jid_cid = + g_strdup_printf("%s@%s/%s%s%s", js->user->node, js->user->domain, + js->user->resource, who, cid); + purple_debug_info("jabber", + "didn't find BoB object by pure CID, try including JIDs: %s\n", + jid_cid); + data = g_hash_table_lookup(remote_data_by_cid, jid_cid); + g_free(jid_cid); + } + return data; } void @@ -342,12 +342,21 @@ } void -jabber_data_associate_remote(JabberData *data) +jabber_data_associate_remote(JabberStream *js, const gchar *who, JabberData *data) { - purple_debug_info("jabber", "associating remote data object, cid = %s\n", - jabber_data_get_cid(data)); - g_hash_table_insert(remote_data_by_cid, g_strdup(jabber_data_get_cid(data)), - data); + gchar *cid; + + if (jabber_data_has_valid_hash(data)) { + cid = g_strdup(jabber_data_get_cid(data)); + } else { + cid = g_strdup_printf("%s@%s/%s%s%s", js->user->node, js->user->domain, + js->user->resource, who, jabber_data_get_cid(data)); + } + + purple_debug_info("jabber", "associating remote BoB object with cid = %s\n", + cid); + + g_hash_table_insert(remote_data_by_cid, cid, data); } void
--- a/libpurple/protocols/jabber/data.h Mon Mar 22 22:26:14 2010 +0000 +++ b/libpurple/protocols/jabber/data.h Wed Mar 24 19:56:07 2010 +0000 @@ -72,11 +72,13 @@ /* lookup functions */ const JabberData *jabber_data_find_local_by_alt(const gchar *alt); const JabberData *jabber_data_find_local_by_cid(const gchar *cid); -const JabberData *jabber_data_find_remote_by_cid(const gchar *cid); +const JabberData *jabber_data_find_remote_by_cid(JabberStream *js, + const gchar *who, const gchar *cid); /* store data objects */ void jabber_data_associate_local(JabberData *data, const gchar *alt); -void jabber_data_associate_remote(JabberData *data); +void jabber_data_associate_remote(JabberStream *js, const gchar *who, + JabberData *data); /* handles iq requests */ void jabber_data_parse(JabberStream *js, const char *who, JabberIqType type,
--- a/libpurple/protocols/jabber/jutil.c Mon Mar 22 22:26:14 2010 +0000 +++ b/libpurple/protocols/jabber/jutil.c Wed Mar 24 19:56:07 2010 +0000 @@ -733,7 +733,7 @@ const gchar *hash_algo) { PurpleCipherContext *context; - static gchar digest[41]; + static gchar digest[129]; /* 512 bits hex + \0 */ context = purple_cipher_context_new_by_name(hash_algo, NULL); if (context == NULL)
--- a/libpurple/protocols/jabber/message.c Mon Mar 22 22:26:14 2010 +0000 +++ b/libpurple/protocols/jabber/message.c Wed Mar 24 19:56:07 2010 +0000 @@ -462,21 +462,22 @@ } static void -jabber_message_add_remote_smileys(const xmlnode *message) +jabber_message_add_remote_smileys(JabberStream *js, const gchar *who, + const xmlnode *message) { xmlnode *data_tag; for (data_tag = xmlnode_get_child_with_namespace(message, "data", NS_BOB) ; data_tag ; data_tag = xmlnode_get_next_twin(data_tag)) { const gchar *cid = xmlnode_get_attrib(data_tag, "cid"); - const JabberData *data = jabber_data_find_remote_by_cid(cid); + const JabberData *data = jabber_data_find_remote_by_cid(js, who, cid); if (!data && cid != NULL) { /* we haven't cached this already, let's add it */ JabberData *new_data = jabber_data_create_from_xml(data_tag); if (new_data) { - jabber_data_associate_remote(new_data); + jabber_data_associate_remote(js, who, new_data); } } } @@ -634,7 +635,7 @@ } /* process any newly provided smileys */ - jabber_message_add_remote_smileys(packet); + jabber_message_add_remote_smileys(js, to, packet); } /* reformat xhtml so that img tags with a "cid:" src gets @@ -660,7 +661,7 @@ if (purple_conv_custom_smiley_add(conv, alt, "cid", cid, TRUE)) { const JabberData *data = - jabber_data_find_remote_by_cid(cid); + jabber_data_find_remote_by_cid(js, from, cid); /* if data is already known, we write it immediatly */ if (data) { purple_debug_info("jabber",