libpurple 32416:acddb4dbee6d: Credit to Andy Spencer for IRC SASL

commits at adium.im commits at adium.im
Wed Oct 17 12:17:34 UTC 2012


details:	http://hg.adium.im/libpurple/rev/acddb4dbee6d
revision:	32416:acddb4dbee6d
branch:		release-2.x.y
author:		Ethan Blanton <elb at pidgin.im>
date:		Sun Sep 30 09:08:33 2012 -0400

Credit to Andy Spencer for IRC SASL
Subject: libpurple 32417:51473787ff4f: Bake the sha1sums for the debug symbols and gtk runtime into the installer instead of downloading them.

details:	http://hg.adium.im/libpurple/rev/51473787ff4f
revision:	32417:51473787ff4f
branch:		release-2.x.y
author:		Daniel Atallah <datallah at pidgin.im>
date:		Tue Oct 02 00:15:20 2012 -0400

Bake the sha1sums for the debug symbols and gtk runtime into the installer instead of downloading them.

 * We should know both of these values at the time we build the installer
 * This also fixes stuff so that we don't regenerate the GTK Runtime after it
   has been published
 ** The various Pidgin versions that share a GTK+ Bundle should now use exactly
    the same file instead of one that contains the same contents
 * Fixes #15277
Subject: libpurple 32418:c259c9a6d184: Fix a couple things about validating the gpg key of downloaded GTK+ bundle components

details:	http://hg.adium.im/libpurple/rev/c259c9a6d184
revision:	32418:c259c9a6d184
branch:		release-2.x.y
author:		Daniel Atallah <datallah at pidgin.im>
date:		Tue Oct 02 00:15:25 2012 -0400

Fix a couple things about validating the gpg key of downloaded GTK+ bundle components

 * Don't import the key into the global public key chain
 * Use a temporary keyring in the staging directory (needs to be an absolute path)
 * Fix an issue creating the temporary keyring (needs to be `touch`ed)
Subject: libpurple 32419:156f37832487: Sign all the win32 binaries with GPG (in addition to the authenticode signing for the executables)

details:	http://hg.adium.im/libpurple/rev/156f37832487
revision:	32419:156f37832487
branch:		release-2.x.y
author:		Daniel Atallah <datallah at pidgin.im>
date:		Tue Oct 02 00:15:25 2012 -0400

Sign all the win32 binaries with GPG (in addition to the authenticode signing for the executables)

 * This is potentially unnecessary for the installers that are authenticode signed,
   but it's at least needed for the other stuff, so i think it's worthwhile to be
   consistent.
Subject: libpurple 32420:a711c88ce448: Patch win32 meanwhile binary with jhkrischel's adium patches to fix #12637

details:	http://hg.adium.im/libpurple/rev/a711c88ce448
revision:	32420:a711c88ce448
branch:		release-2.x.y
author:		Daniel Atallah <datallah at pidgin.im>
date:		Fri Oct 05 00:51:20 2012 +0100

Patch win32 meanwhile binary with jhkrischel's adium patches to fix #12637
Subject: libpurple 32421:1a805821b6f3: Add various win32 changes to ChangeLog

details:	http://hg.adium.im/libpurple/rev/1a805821b6f3
revision:	32421:1a805821b6f3
branch:		release-2.x.y
author:		Daniel Atallah <datallah at pidgin.im>
date:		Fri Oct 05 00:53:32 2012 +0100

Add various win32 changes to ChangeLog
Subject: libpurple 32422:d1a5a89aa454: Credit Jonathan Rice for the libmeanwhile patch. Refs #12637

details:	http://hg.adium.im/libpurple/rev/d1a5a89aa454
revision:	32422:d1a5a89aa454
branch:		release-2.x.y
author:		Daniel Atallah <datallah at pidgin.im>
date:		Mon Oct 08 18:30:55 2012 +0100

Credit Jonathan Rice for the libmeanwhile patch. Refs #12637
Subject: libpurple 32423:c10f36e28024: Fix Coverity CID 732167 (missing va_end in oscar.c:purple_parse_clientauto)

details:	http://hg.adium.im/libpurple/rev/c10f36e28024
revision:	32423:c10f36e28024
branch:		release-2.x.y
author:		Daniel Atallah <datallah at pidgin.im>
date:		Mon Oct 08 23:54:45 2012 -0400

Fix Coverity CID 732167 (missing va_end in oscar.c:purple_parse_clientauto)

 * also refactor sloppy code to resolve CIDs 732165 and 732166
Subject: libpurple 32424:581716bd2b64: Fix a couple small gg leaks - CID 732083, 732084 and one more that I noticed

details:	http://hg.adium.im/libpurple/rev/581716bd2b64
revision:	32424:581716bd2b64
branch:		release-2.x.y
author:		Daniel Atallah <datallah at pidgin.im>
date:		Tue Oct 09 00:58:01 2012 -0400

Fix a couple small gg leaks - CID 732083, 732084 and one more that I noticed
Subject: libpurple 32425:eafc92ac5f87: Merged release-2.x.y into adium

details:	http://hg.adium.im/libpurple/rev/eafc92ac5f87
revision:	32425:eafc92ac5f87
branch:		adium
author:		Thijs Alkemade <thijsalkemade at gmail.com>
date:		Wed Oct 17 14:17:21 2012 +0200

Merged release-2.x.y into adium

diffs (truncated from 1289 to 1000 lines):

diff -r fb9fe934688e -r eafc92ac5f87 .hgignore
--- a/.hgignore	Thu Sep 27 00:23:57 2012 -0400
+++ b/.hgignore	Wed Oct 17 14:17:21 2012 +0200
@@ -9,6 +9,7 @@
 .*/perl/common/pm_to_blib$
 .*~$
 .*\.a$
+.*\.asc$
 .*\.bak$
 .*\.bs$
 .*\.def$
diff -r fb9fe934688e -r eafc92ac5f87 ChangeLog
--- a/ChangeLog	Thu Sep 27 00:23:57 2012 -0400
+++ b/ChangeLog	Wed Oct 17 14:17:21 2012 +0200
@@ -9,7 +9,8 @@
 	  buddies will be disabled till 3.0.0. (#15226, #14305)
 
 	IRC:
-	* Support for SASL authentication.  (Thijs Alkemade) (#13270)
+	* Support for SASL authentication.  (Thijs Alkemade, Andy Spencer)
+	  (#13270)
 
 	MSN:
 	* Fix a crash when removing a user before its icon is loaded. (Mark
@@ -21,7 +22,28 @@
 
 	Plugins:
 	* The Voice/Video Settings plugin supports using the sndio GStreamer
-	 backends. (Brad Smith) (#14414)
+	  backends. (Brad Smith) (#14414)
+
+	Windows-Specific Changes:
+	* Compile with secure flags (#15290)
+	* Installer downloads GTK+ Runtime and Debug Symbols more securely.
+	  (#15277)
+	* Updates to a number of dependencies, some of which have security
+	  related fixes. (#14571, #15285, #15286)
+	 * ATK 1.32.0-2
+	 * Cyrus SASL 2.1.25
+	 * expat 2.1.0-1
+	 * freetype 2.4.10-1
+	 * gettext 0.18.1.1-2
+	 * Glib 2.28.8-1
+	 * libpng 1.4.12-1
+	 * libxml2 2.9.0-1
+	 * NSS 3.13.6 and NSPR 4.9.2
+	 * Pango 1.29.4-1
+	 * SILC 1.1.10
+	 * zlib 1.2.5-2
+	* Patch libmeanwhile (sametime library) to fix crash. (Jonathan Rice)
+	  (#12637)
 
 version 2.10.6 (07/06/2012):
 	Pidgin:
diff -r fb9fe934688e -r eafc92ac5f87 Makefile.mingw
--- a/Makefile.mingw	Thu Sep 27 00:23:57 2012 -0400
+++ b/Makefile.mingw	Wed Oct 17 14:17:21 2012 +0200
@@ -33,6 +33,15 @@
 
 GTK_INSTALL_VERSION = 2.16.6.1
 
+authenticode_sign = $(MONO_SIGNCODE) \
+		    -spc "$(SIGNCODE_SPC)" -v "$(SIGNCODE_PVK)" \
+		    -a sha1 -$$ commercial \
+		    -n "$(2)" -i "https://pidgin.im" \
+		    -t "http://timestamp.verisign.com/scripts/timstamp.dll" -tr 10 \
+		    $(1)
+
+gpg_sign = $(GPG_SIGN) -ab $(1) && $(GPG_SIGN) --verify $(1).asc
+
 STRIPPED_RELEASE_DIR = $(PIDGIN_TREE_TOP)/pidgin-$(PIDGIN_VERSION)-win32bin
 DEBUG_SYMBOLS_DIR = $(PIDGIN_TREE_TOP)/pidgin-$(PIDGIN_VERSION)-dbgsym
 
@@ -78,7 +87,7 @@
 
 include $(PIDGIN_COMMON_RULES)
 
-.PHONY: all docs install installer installer_offline installer_zip debug_symbols_zip installers clean uninstall create_release_install_dir generate_installer_includes $(PIDGIN_REVISION_H) $(PIDGIN_REVISION_RAW_TXT)
+.PHONY: all docs install installer installer_offline installer_zip debug_symbols_zip installers clean uninstall create_release_install_dir generate_installer_includes $(PIDGIN_REVISION_H) $(PIDGIN_REVISION_RAW_TXT) gtk_runtime_zip
 
 all: $(PIDGIN_CONFIG_H) $(PIDGIN_REVISION_H)
 	$(MAKE) -C $(PURPLE_TOP) -f $(MINGW_MAKEFILE)
@@ -102,10 +111,10 @@
 	cp $(WIN32_DEV_TOP)/pidgin-inst-deps-20100315/exchndl.dll $(PIDGIN_INSTALL_DIR)
 	cp $(GCC_SSP_TOP)/bin/libssp-0.dll $(PIDGIN_INSTALL_DIR)
 
-pidgin/win32/nsis/gtk-runtime-$(GTK_BUNDLE_VERSION).zip:
-	pidgin/win32/nsis/generate_gtk_zip.sh `pwd`
+gtk_runtime_zip:
+	pidgin/win32/nsis/generate_gtk_zip.sh "`pwd`" "$(GPG_SIGN)"
 
-generate_installer_includes: create_release_install_dir pidgin/win32/nsis/gtk-runtime-$(GTK_BUNDLE_VERSION).zip debug_symbols_zip $(PIDGIN_TREE_TOP)/pidgin/win32/nsis/nsis_translations.desktop
+generate_installer_includes: create_release_install_dir gtk_runtime_zip debug_symbols_zip $(PIDGIN_TREE_TOP)/pidgin/win32/nsis/nsis_translations.desktop
 	rm -f pidgin/win32/nsis/pidgin-translations.nsh pidgin/win32/nsis/pidgin-spellcheck.nsh pidgin/win32/nsis/pidgin-spellcheck-preselect.nsh
 	find $(STRIPPED_RELEASE_DIR)/locale -maxdepth 1 -mindepth 1 \
 	 -exec basename {} ';' \
@@ -139,36 +148,32 @@
 	find $(STRIPPED_RELEASE_DIR) \( -name '*.dll' -o -name '*.exe' \) \
 	 -not \( -false $(EXTERNAL_DLLS_FIND_EXP) \) \
 	 -exec $(STRIP) --strip-unneeded {} ';'
-	$(MONO_SIGNCODE) \
-		-spc "$(SIGNCODE_SPC)" -v "$(SIGNCODE_PVK)" \
-		-a sha1 -$$ commercial \
-		-n "Pidgin $(PIDGIN_VERSION)" -i "https://pidgin.im" \
-		-t "http://timestamp.verisign.com/scripts/timstamp.dll" -tr 10 \
-		$(STRIPPED_RELEASE_DIR)/pidgin.exe
+	$(call authenticode_sign, $(STRIPPED_RELEASE_DIR)/pidgin.exe, "Pidgin $(PIDGIN_VERSION)")
 
 installer: generate_installer_includes
-	$(MAKENSIS) -V3 -DPIDGIN_VERSION="$(PIDGIN_VERSION)" -DPIDGIN_PRODUCT_VERSION="$(PIDGIN_PRODUCT_VERSION)" -DPIDGIN_INSTALL_DIR="$(STRIPPED_RELEASE_DIR)" -DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" pidgin/win32/nsis/pidgin-installer.nsi
-	$(MONO_SIGNCODE) \
-		-spc "$(SIGNCODE_SPC)" -v "$(SIGNCODE_PVK)" \
-		-a sha1 -$$ commercial \
-		-n "Pidgin Installer" -i "https://pidgin.im" \
-		-t "http://timestamp.verisign.com/scripts/timstamp.dll" -tr 10 \
-		pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION).exe
+	$(eval $@_DEBUG_SYMBOLS_SHA1SUM := $(shell sha1sum $(DEBUG_SYMBOLS_DIR).zip | sed -e "s/\ .*$$//"))
+	$(eval $@_GTK_SHA1SUM := $(shell sha1sum pidgin/win32/nsis/gtk-runtime-$(GTK_INSTALL_VERSION).zip | sed -e "s/\ .*$$//"))
+	$(MAKENSIS) -V3 -DPIDGIN_VERSION="$(PIDGIN_VERSION)" -DPIDGIN_PRODUCT_VERSION="$(PIDGIN_PRODUCT_VERSION)" \
+		-DPIDGIN_INSTALL_DIR="$(STRIPPED_RELEASE_DIR)" -DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" \
+		-DDEBUG_SYMBOLS_SHA1SUM="$($@_DEBUG_SYMBOLS_SHA1SUM)" -DGTK_SHA1SUM="$($@_GTK_SHA1SUM)"\
+		pidgin/win32/nsis/pidgin-installer.nsi
+	$(call authenticode_sign, pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION).exe, "Pidgin Installer")
 	mv pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION).exe ./
+	$(call gpg_sign, pidgin-$(PIDGIN_VERSION).exe)
 
 installer_offline: generate_installer_includes
-	$(MAKENSIS) -V3 -DPIDGIN_VERSION="$(PIDGIN_VERSION)" -DPIDGIN_PRODUCT_VERSION="$(PIDGIN_PRODUCT_VERSION)" -DOFFLINE_INSTALLER -DPIDGIN_INSTALL_DIR="$(STRIPPED_RELEASE_DIR)" -DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" pidgin/win32/nsis/pidgin-installer.nsi
-	$(MONO_SIGNCODE) \
-		-spc "$(SIGNCODE_SPC)" -v "$(SIGNCODE_PVK)" \
-		-a sha1 -$$ commercial \
-		-n "Pidgin Installer" -i "https://pidgin.im" \
-		-t "http://timestamp.verisign.com/scripts/timstamp.dll" -tr 10 \
-		pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION)-offline.exe
+	$(MAKENSIS) -V3 -DPIDGIN_VERSION="$(PIDGIN_VERSION)" -DPIDGIN_PRODUCT_VERSION="$(PIDGIN_PRODUCT_VERSION)" \
+		-DPIDGIN_INSTALL_DIR="$(STRIPPED_RELEASE_DIR)" -DGTK_INSTALL_VERSION="$(GTK_INSTALL_VERSION)" \
+		-DOFFLINE_INSTALLER \
+		pidgin/win32/nsis/pidgin-installer.nsi
+	$(call authenticode_sign, pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION)-offline.exe, "Pidgin Installer")
 	mv pidgin/win32/nsis/pidgin-$(PIDGIN_VERSION)-offline.exe ./
+	$(call gpg_sign, pidgin-$(PIDGIN_VERSION)-offline.exe)
 
 installer_zip: create_release_install_dir
 	rm -f pidgin-$(PIDGIN_VERSION)-win32-bin.zip
 	zip -9 -r pidgin-$(PIDGIN_VERSION)-win32-bin.zip $(STRIPPED_RELEASE_DIR)
+	$(call gpg_sign, pidgin-$(PIDGIN_VERSION)-win32-bin.zip)
 
 debug_symbols_zip: install
 	rm -rf $(DEBUG_SYMBOLS_DIR) $(DEBUG_SYMBOLS_DIR).zip
@@ -176,7 +181,9 @@
 	tar -cf - `find $(PIDGIN_INSTALL_DIR) \( -name '*.dll' -o -name '*.exe' \) \
 	 -not \( -false $(EXTERNAL_DLLS_FIND_EXP) \) -print` \
 	 | tar --strip 2 --xform s/$$/.dbgsym/ -xC $(DEBUG_SYMBOLS_DIR) -f -
+	cp $(MEANWHILE_TOP)/bin/libmeanwhile-1.dll.unstripped $(DEBUG_SYMBOLS_DIR)/libmeanwhile-1.dll.dbgsym
 	zip -9 -r $(DEBUG_SYMBOLS_DIR).zip $(DEBUG_SYMBOLS_DIR) 
+	$(call gpg_sign, $(DEBUG_SYMBOLS_DIR).zip)
 
 installers: installer installer_offline debug_symbols_zip installer_zip
 
diff -r fb9fe934688e -r eafc92ac5f87 configure.ac
--- a/configure.ac	Thu Sep 27 00:23:57 2012 -0400
+++ b/configure.ac	Wed Oct 17 14:17:21 2012 +0200
@@ -2673,3 +2673,4 @@
 echo configure complete, now type \'make\'
 echo
 
+
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/Makefile.am
--- a/libpurple/Makefile.am	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/Makefile.am	Wed Oct 17 14:17:21 2012 +0200
@@ -301,6 +301,7 @@
 libpurple_la_LDFLAGS = -export-dynamic -version-info $(PURPLE_LT_VERSION_INFO) -no-undefined
 libpurple_la_LIBADD = \
 	$(STATIC_LINK_LIBS) \
+	$(KRB4_LDFLAGS) $(KRB4_LIBS) \
 	$(DBUS_LIBS) \
 	$(GLIB_LIBS) \
 	$(LIBXML_LIBS) \
@@ -311,6 +312,8 @@
 	$(GSTINTERFACES_LIBS) \
 	$(IDN_LIBS) \
 	ciphers/libpurple-ciphers.la \
+	$(SASL_LIBS) \
+	$(MEANWHILE_LIBS) \
 	-lm
 
 AM_CPPFLAGS = \
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/account.c
--- a/libpurple/account.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/account.c	Wed Oct 17 14:17:21 2012 +0200
@@ -413,11 +413,16 @@
 		g_hash_table_foreach(account->ui_settings, ui_setting_to_xmlnode, node);
 	}
 
+	// Adium never wants its proxy information saved to disk.
+	/*
+		
 	if ((proxy_info = purple_account_get_proxy_info(account)) != NULL)
 	{
 		child = proxy_settings_to_xmlnode(proxy_info);
 		xmlnode_insert_child(node, child);
 	}
+	
+	*/
 
 	child = current_error_to_xmlnode(priv->current_error);
 	xmlnode_insert_child(node, child);
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/blist.c
--- a/libpurple/blist.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/blist.c	Wed Oct 17 14:17:21 2012 +0200
@@ -923,7 +923,7 @@
 	} else if (!purple_status_is_online(status) &&
 				purple_status_is_online(old_status)) {
 
-		purple_blist_node_set_int(&buddy->node, "last_seen", time(NULL));
+/*		purple_blist_node_set_int(&buddy->node, "last_seen", time(NULL)); */
 		purple_signal_emit(purple_blist_get_handle(), "buddy-signed-off", buddy);
 
 		cnode = buddy->node.parent;
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/dnssrv.c
--- a/libpurple/dnssrv.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/dnssrv.c	Wed Oct 17 14:17:21 2012 +0200
@@ -1090,12 +1090,17 @@
 }
 
 static void
-purple_srv_query_failed(PurpleSrvTxtQueryData *query_data, const gchar *error_message)
+purple_srv_txt_query_failed(PurpleSrvTxtQueryData *query_data, const gchar *error_message)
 {
-	purple_debug_error("dnssrv", "%s\n", error_message);
+	purple_debug_error("dnssrv", "purple_srv_txt_query_failed: %s\n", error_message);
 
-	if (query_data->cb.srv != NULL)
-		query_data->cb.srv(NULL, 0, query_data->extradata);
+	if (query_data->type == T_SRV) {
+		if (query_data->cb.srv != NULL)
+			query_data->cb.srv(NULL, 0, query_data->extradata);
+	} else if (query_data->type == T_TXT) {
+		if (query_data->cb.txt != NULL)
+			query_data->cb.txt(NULL, query_data->extradata);
+	}
 
 	purple_srv_txt_query_destroy(query_data);
 }
@@ -1106,7 +1111,7 @@
 	PurpleSrvTxtQueryUiOps *ops = purple_srv_txt_query_get_ui_ops();
 
 	if (ops && ops->resolve)
-		return ops->resolve(query_data, (query_data->type == T_SRV ? purple_srv_query_resolved : purple_txt_query_resolved), purple_srv_query_failed);
+		return ops->resolve(query_data, (query_data->type == T_SRV ? purple_srv_query_resolved : purple_txt_query_resolved), purple_srv_txt_query_failed);
 
 	return FALSE;
 }
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/gg/gg.c	Wed Oct 17 14:17:21 2012 +0200
@@ -2177,6 +2177,7 @@
 
 		glp->server_addr = inet_addr(inet_ntoa(*addr));
 		glp->server_port = 8074;
+		free(addr);
 	} else
 		purple_debug_info("gg", "Trying to retrieve address from gg appmsg service\n");
 
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/gg/search.c
--- a/libpurple/protocols/gg/search.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/gg/search.c	Wed Oct 17 14:17:21 2012 +0200
@@ -138,6 +138,7 @@
 	GGPInfo *info = gc->proto_data;
 	gg_pubdir50_t req;
 	guint seq, offset;
+	gchar *tmp;
 
 	purple_debug_info("gg", "It's time to perform a search...\n");
 
@@ -190,10 +191,13 @@
 	offset = form->page_size * form->page_number;
 	purple_debug_info("gg", "page number: %u, page size: %u, offset: %u\n",
 		form->page_number, form->page_size, offset);
-	gg_pubdir50_add(req, GG_PUBDIR50_START, g_strdup_printf("%u", offset));
+	tmp = g_strdup_printf("%u", offset);
+	gg_pubdir50_add(req, GG_PUBDIR50_START, tmp);
+	g_free(tmp);
 
 	if ((seq = gg_pubdir50(info->session, req)) == 0) {
 		purple_debug_warning("gg", "ggp_bmenu_show_details: Search failed.\n");
+		gg_pubdir50_free(req);
 		return 0;
 	}
 
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/jabber/auth_cyrus.c
--- a/libpurple/protocols/jabber/auth_cyrus.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/jabber/auth_cyrus.c	Wed Oct 17 14:17:21 2012 +0200
@@ -333,6 +333,23 @@
 			}
 		}
 
+		if (purple_strequal(js->current_mech, "DIGEST-MD5")) {
+			/* CYRUS-SASL's DIGEST-MD5 and Java's DIGEST-MD5 are mutually incompatible because of different interpretations of RFC2831.
+			 * This means that if we are using SASL and connecting to a Java-based server such as OpenFire, we will receive an authentication
+			 * failure if that server offers DIGEST-MD5 in such a way that SASL chooses it as the best mechanism for us.
+			 *
+			 * However, we implement our own DIGEST-MD5 for use when we're compiled without SASL support, and that implementation
+			 * works correctly. Therefore, if SASL chooses DIGEST-MD5, we switch over to our own implementation.
+			 * jabber_auth_handle_challenge() will take it from there.
+			 *
+			 * SASL would change state to SASL_OK after when handling the challenge; we do so immediately to avoid an error later.
+			 */
+			js->auth_mech = jabber_auth_get_digest_md5_mech();
+			js->sasl_state = SASL_OK;
+			sasl_dispose(&js->sasl);
+			js->sasl = NULL;
+		}
+
 		*reply = auth;
 		return JABBER_SASL_STATE_CONTINUE;
 	} else {
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/jabber/message.c
--- a/libpurple/protocols/jabber/message.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/jabber/message.c	Wed Oct 17 14:17:21 2012 +0200
@@ -638,6 +638,8 @@
 					jabber_message_add_remote_smileys(js, to, packet);
 				}
 
+				xmlnode_strip_prefixes(child);
+
 				/* reformat xhtml so that img tags with a "cid:" src gets
 				  translated to the bare text of the emoticon (the "alt" attrib) */
 				/* this is done also when custom smiley retrieval is turned off,
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/jabber/parser.c
--- a/libpurple/protocols/jabber/parser.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/jabber/parser.c	Wed Oct 17 14:17:21 2012 +0200
@@ -261,6 +261,8 @@
 
 void jabber_parser_free(JabberStream *js) {
 	if (js->context) {
+		xmlSetStructuredErrorFunc(NULL, jabber_parser_structured_error_handler);
+
 		xmlParseChunk(js->context, NULL,0,1);
 		xmlFreeParserCtxt(js->context);
 		js->context = NULL;
@@ -271,6 +273,8 @@
 {
 	int ret;
 
+	xmlSetStructuredErrorFunc(NULL, jabber_parser_structured_error_handler);
+
 	if (js->context == NULL) {
 		/* libxml inconsistently starts parsing on creating the
 		 * parser, so do a ParseChunk right afterwards to force it. */
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/jabber/roster.c
--- a/libpurple/protocols/jabber/roster.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/jabber/roster.c	Wed Oct 17 14:17:21 2012 +0200
@@ -331,7 +331,7 @@
 		                  name, tmp);
 		g_free(tmp);
 	}
-
+					  
 	iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:roster");
 
 	query = xmlnode_get_child(iq->node, "query");
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/msn/oim.c
--- a/libpurple/protocols/msn/oim.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/msn/oim.c	Wed Oct 17 14:17:21 2012 +0200
@@ -805,8 +805,6 @@
 msn_parse_oim_xml(MsnOim *oim, xmlnode *node)
 {
 	xmlnode *mNode;
-	xmlnode *iu_node;
-	MsnSession *session = oim->session;
 
 	g_return_if_fail(node != NULL);
 
@@ -817,22 +815,6 @@
 		return;
 	}
 
-	iu_node = xmlnode_get_child(node, "E/IU");
-
-	if (iu_node != NULL && purple_account_get_check_mail(session->account))
-	{
-		char *unread = xmlnode_get_data(iu_node);
-		const char *passports[2] = { msn_user_get_passport(session->user) };
-		const char *urls[2] = { session->passport_info.mail_url };
-		int count = atoi(unread);
-
-		/* XXX/khc: pretty sure this is wrong */
-		if (count > 0)
-			purple_notify_emails(session->account->gc, count, FALSE, NULL,
-				NULL, passports, urls, NULL, NULL);
-		g_free(unread);
-	}
-
 	for(mNode = xmlnode_get_child(node, "M"); mNode;
 					mNode = xmlnode_get_next_twin(mNode)){
 		char *passport, *msgid, *nickname, *rtime = NULL;
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/myspace/message.c
--- a/libpurple/protocols/myspace/message.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/myspace/message.c	Wed Oct 17 14:17:21 2012 +0200
@@ -129,7 +129,7 @@
  *
  * @param first_key The first argument (a key), or NULL to take all arguments
  *    from argp.
- * @param argp A va_list of variadic arguments, already started with va_start(). Will be va_end()'d.
+ * @param argp A va_list of variadic arguments, already started with va_start().
  * @return New MsimMessage *, must be freed with msim_msg_free().
  *
  * For internal use - users probably want msim_msg_new() or msim_send().
@@ -211,7 +211,6 @@
 				break;
 		}
 	} while(key);
-	va_end(argp);
 
 	return msg;
 }
@@ -227,14 +226,16 @@
 MsimMessage *
 msim_msg_new(gchar *first_key, ...)
 {
+	MsimMessage *ret = NULL;
 	va_list argp;
 
 	if (first_key) {
-	va_start(argp, first_key);
-		return msim_msg_new_v(first_key, argp);
-	} else {
-		return NULL;
+		va_start(argp, first_key);
+		ret = msim_msg_new_v(first_key, argp);
+		va_end(argp);
 	}
+
+	return ret;
 }
 
 /**
@@ -960,6 +961,7 @@
 
 	va_start(argp, session);
 	msg = msim_msg_new_v(NULL, argp);
+	va_end(argp);
 
 	/* Actually send the message. */
 	success = msim_msg_send(session, msg);
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/oscar/oscar.c
--- a/libpurple/protocols/oscar/oscar.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/oscar/oscar.c	Wed Oct 17 14:17:21 2012 +0200
@@ -2342,6 +2342,7 @@
 	va_list ap;
 	guint16 chan, reason;
 	char *who;
+	int ret = 1;
 
 	va_start(ap, fr);
 	chan = (guint16)va_arg(ap, unsigned int);
@@ -2350,7 +2351,7 @@
 
 	if (chan == 0x0002) { /* File transfer declined */
 		guchar *cookie = va_arg(ap, guchar *);
-		return purple_parse_clientauto_ch2(od, who, reason, cookie);
+		ret = purple_parse_clientauto_ch2(od, who, reason, cookie);
 	} else if (chan == 0x0004) { /* ICQ message */
 		guint32 state = 0;
 		char *msg = NULL;
@@ -2358,12 +2359,12 @@
 			state = va_arg(ap, guint32);
 			msg = va_arg(ap, char *);
 		}
-		return purple_parse_clientauto_ch4(od, who, reason, state, msg);
+		ret = purple_parse_clientauto_ch4(od, who, reason, state, msg);
 	}
 
 	va_end(ap);
 
-	return 1;
+	return ret;
 }
 
 static int purple_parse_genericerr(OscarData *od, FlapConnection *conn, FlapFrame *fr, ...) {
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/protocols/yahoo/libymsg.c
--- a/libpurple/protocols/yahoo/libymsg.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/protocols/yahoo/libymsg.c	Wed Oct 17 14:17:21 2012 +0200
@@ -5152,6 +5152,9 @@
 	YahooFriend *f = yahoo_friend_find(gc, who);
 	const char *temp = NULL;
 
+	purple_debug_info("yahoo", "Moving buddy %s from %s to %s",
+					  who, old_group, new_group);
+
 	/* Step 0:  If they aren't on the server list anyway,
 	 *          don't bother letting the server know.
 	 */
@@ -5184,6 +5187,9 @@
 		yahoo_packet_hash(pkt, "ssssssss", 1, purple_connection_get_display_name(gc),
 	                  302, "240", 300, "240", 7, temp, 224, gpo, 264, gpn, 301,
 	                  "240", 303, "240");
+
+	purple_debug_info("yahoo", "Performing move");
+
 	yahoo_packet_send_and_free(pkt, yd);
 
 	g_free(gpn);
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/sslconn.c
--- a/libpurple/sslconn.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/sslconn.c	Wed Oct 17 14:17:21 2012 +0200
@@ -144,6 +144,8 @@
 		return NULL;
 	}
 
+	gsc->account = account;
+
 	return (PurpleSslConnection *)gsc;
 }
 
@@ -225,6 +227,7 @@
 	/* TODO: Move this elsewhere */
 	gsc->verifier = purple_certificate_find_verifier("x509","tls_cached");
 
+	gsc->account = account;
 
 	ops = purple_ssl_get_ops();
 	ops->connectfunc(gsc);
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/sslconn.h
--- a/libpurple/sslconn.h	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/sslconn.h	Wed Oct 17 14:17:21 2012 +0200
@@ -77,6 +77,9 @@
 
 	/** Verifier to use in authenticating the peer */
 	PurpleCertificateVerifier *verifier;
+
+	/** Handle to the account for which this connection is being made. Can be NULL. */
+	PurpleAccount *account;
 };
 
 /**
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/tests/test_xmlnode.c
--- a/libpurple/tests/test_xmlnode.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/tests/test_xmlnode.c	Wed Oct 17 14:17:21 2012 +0200
@@ -21,6 +21,101 @@
 }
 END_TEST
 
+#define check_doc_structure(x) { \
+	xmlnode *ping, *child1, *child2; \
+	fail_if(x == NULL, "Failed to parse document"); \
+	ping = xmlnode_get_child(x, "ping"); \
+	fail_if(ping == NULL, "Failed to find 'ping' child"); \
+	child1 = xmlnode_get_child(ping, "child1"); \
+	fail_if(child1 == NULL, "Failed to find 'child1'"); \
+	child2 = xmlnode_get_child(child1, "child2"); \
+	fail_if(child2 == NULL, "Failed to find 'child2'"); \
+	xmlnode_new_child(child2, "a"); \
+	\
+	assert_string_equal("jabber:client", xmlnode_get_namespace(x)); \
+	/* NOTE: xmlnode_get_namespace() returns the namespace of the element, not the
+	 * current default namespace.  See http://www.w3.org/TR/xml-names/#defaulting and
+	 * http://www.w3.org/TR/xml-names/#dt-defaultNS.
+	 */ \
+	assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(ping)); \
+	assert_string_equal("jabber:client", xmlnode_get_namespace(child1)); \
+	assert_string_equal("urn:xmpp:ping", xmlnode_get_namespace(child2)); \
+	/*
+	 * This fails (well, actually crashes [the ns is NULL]) unless
+	 * xmlnode_new_child() actually sets the element namespace.
+	assert_string_equal("jabber:client", xmlnode_get_namespace(xmlnode_get_child(child2, "a")));
+	 */ \
+	\
+	assert_string_equal("jabber:client", xmlnode_get_default_namespace(x)); \
+	assert_string_equal("jabber:client", xmlnode_get_default_namespace(ping)); \
+	assert_string_equal("jabber:client", xmlnode_get_default_namespace(child1)); \
+	assert_string_equal("jabber:client", xmlnode_get_default_namespace(child2)); \
+}
+
+START_TEST(test_xmlnode_prefixes)
+{
+	const char *xml_doc =
+		"<iq type='get' xmlns='jabber:client' xmlns:ping='urn:xmpp:ping'>"
+			"<ping:ping>"
+				"<child1>"
+					"<ping:child2></ping:child2>" /* xmlns='jabber:child' */
+				"</child1>"
+			"</ping:ping>"
+		"</iq>";
+	char *str;
+	xmlnode *xml, *reparsed;
+
+	xml = xmlnode_from_str(xml_doc, -1);
+	check_doc_structure(xml);
+
+	/* Check that xmlnode_from_str(xmlnode_to_str(xml, NULL), -1) is idempotent. */
+	str = xmlnode_to_str(xml, NULL);
+	fail_if(str == NULL, "Failed to serialize XMLnode");
+	reparsed = xmlnode_from_str(str, -1);
+	fail_if(reparsed == NULL, "Failed to reparse xml document");
+	check_doc_structure(reparsed);
+
+	g_free(str);
+	xmlnode_free(xml);
+	xmlnode_free(reparsed);
+}
+END_TEST
+
+
+START_TEST(test_strip_prefixes)
+{
+	const char *xml_doc = "<message xmlns='jabber:client' from='user at gmail.com/resource' to='another_user at darkrain42.org' type='chat' id='purple'>"
+		"<cha:active xmlns:cha='http://jabber.org/protocol/chatstates'/>"
+		"<body>xvlc xvlc</body>"
+		"<im:html xmlns:im='http://jabber.org/protocol/xhtml-im'>"
+			"<xht:body xmlns:xht='http://www.w3.org/1999/xhtml'>"
+				"<xht:p>xvlc <xht:span style='font-weight: bold;'>xvlc</xht:span></xht:p>"
+			"</xht:body>"
+		"</im:html>"
+	"</message>";
+	const char *out = "<message xmlns='jabber:client' from='user at gmail.com/resource' to='another_user at darkrain42.org' type='chat' id='purple'>"
+		"<active xmlns:cha='http://jabber.org/protocol/chatstates' xmlns='http://jabber.org/protocol/chatstates'/>"
+		"<body>xvlc xvlc</body>"
+		"<html xmlns:im='http://jabber.org/protocol/xhtml-im' xmlns='http://jabber.org/protocol/xhtml-im'>"
+			"<body xmlns:xht='http://www.w3.org/1999/xhtml' xmlns='http://www.w3.org/1999/xhtml'>"
+				"<p>xvlc <span style='font-weight: bold;'>xvlc</span></p>"
+			"</body>"
+		"</html>"
+	"</message>";
+	char *str;
+	xmlnode *xml;
+
+	xml = xmlnode_from_str(xml_doc, -1);
+	fail_if(xml == NULL, "Failed to parse XML");
+
+	xmlnode_strip_prefixes(xml);
+	str = xmlnode_to_str(xml, NULL);
+	assert_string_equal_free(out, str);
+
+	xmlnode_free(xml);
+}
+END_TEST
+
 Suite *
 xmlnode_suite(void)
 {
@@ -28,6 +123,9 @@
 
 	TCase *tc = tcase_create("xmlnode");
 	tcase_add_test(tc, test_xmlnode_billion_laughs_attack);
+	tcase_add_test(tc, test_xmlnode_prefixes);
+	tcase_add_test(tc, test_strip_prefixes);
+
 	suite_add_tcase(s, tc);
 
 	return s;
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/win32/global.mak
--- a/libpurple/win32/global.mak	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/win32/global.mak	Wed Oct 17 14:17:21 2012 +0200
@@ -16,7 +16,7 @@
 GTK_BIN ?= $(GTK_TOP)/bin
 BONJOUR_TOP ?= $(WIN32_DEV_TOP)/Bonjour_SDK
 LIBXML2_TOP ?= $(WIN32_DEV_TOP)/libxml2-2.9.0
-MEANWHILE_TOP ?= $(WIN32_DEV_TOP)/meanwhile-1.0.2_daa2
+MEANWHILE_TOP ?= $(WIN32_DEV_TOP)/meanwhile-1.0.2_daa3
 NSS_TOP ?= $(WIN32_DEV_TOP)/nss-3.13.6-nspr-4.9.2
 PERL_LIB_TOP ?= $(WIN32_DEV_TOP)/perl-5.10.0
 SILC_TOOLKIT ?= $(WIN32_DEV_TOP)/silc-toolkit-1.1.10
@@ -110,6 +110,7 @@
 STRIP ?= strip
 INTLTOOL_MERGE ?= $(WIN32_DEV_TOP)/intltool_0.40.4-1_win32/bin/intltool-merge
 MONO_SIGNCODE ?= signcode
+GPG_SIGN ?= gpg
 
 PIDGIN_COMMON_RULES := $(PURPLE_TOP)/win32/rules.mak
 PIDGIN_COMMON_TARGETS := $(PURPLE_TOP)/win32/targets.mak
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/xmlnode.c
--- a/libpurple/xmlnode.c	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/xmlnode.c	Wed Oct 17 14:17:21 2012 +0200
@@ -78,6 +78,19 @@
 	node = new_node(name, XMLNODE_TYPE_TAG);
 
 	xmlnode_insert_child(parent, node);
+#if 0
+	/* This would give xmlnodes more appropriate namespacing
+	 * when creating them.  Otherwise, unless an explicit namespace
+	 * is set, xmlnode_get_namespace() will return NULL, when
+	 * there may be a default namespace.
+	 *
+	 * I'm unconvinced that it's useful, and concerned it may break things.
+	 *
+	 * _insert_child would need the same thing, probably (assuming
+	 * xmlns->node == NULL)
+	 */
+	xmlnode_set_namespace(node, xmlnode_get_default_namespace(node))
+#endif
 
 	return node;
 }
@@ -261,19 +274,53 @@
 
 void xmlnode_set_namespace(xmlnode *node, const char *xmlns)
 {
+	char *tmp;
 	g_return_if_fail(node != NULL);
 
-	g_free(node->xmlns);
+	tmp = node->xmlns;
 	node->xmlns = g_strdup(xmlns);
+
+	if (node->namespace_map) {
+		g_hash_table_insert(node->namespace_map,
+			g_strdup(""), g_strdup(xmlns));
+	}
+
+	g_free(tmp);
 }
 
-const char *xmlnode_get_namespace(xmlnode *node)
+const char *xmlnode_get_namespace(const xmlnode *node)
 {
 	g_return_val_if_fail(node != NULL, NULL);
 
 	return node->xmlns;
 }
 
+const char *xmlnode_get_default_namespace(const xmlnode *node)
+{
+	const xmlnode *current_node;
+	const char *ns = NULL;
+
+	g_return_val_if_fail(node != NULL, NULL);
+
+	current_node = node;
+	while (current_node) {
+		/* If this node does *not* have a prefix, node->xmlns is the default
+		 * namespace.  Otherwise, it's the prefix namespace.
+		 */
+		if (!current_node->prefix && current_node->xmlns) {
+			return current_node->xmlns;
+		} else if (current_node->namespace_map) {
+			ns = g_hash_table_lookup(current_node->namespace_map, "");
+			if (ns && *ns)
+				return ns;
+		}
+
+		current_node = current_node->parent;
+	}
+
+	return ns;
+}
+
 void xmlnode_set_prefix(xmlnode *node, const char *prefix)
 {
 	g_return_if_fail(node != NULL);
@@ -288,6 +335,53 @@
 	return node->prefix;
 }
 
+const char *xmlnode_get_prefix_namespace(const xmlnode *node, const char *prefix)
+{
+	const xmlnode *current_node;
+
+	g_return_val_if_fail(node != NULL, NULL);
+	g_return_val_if_fail(prefix != NULL, xmlnode_get_default_namespace(node));
+
+	current_node = node;
+	while (current_node) {
+		if (current_node->prefix && g_str_equal(prefix, current_node->prefix) &&
+				current_node->xmlns) {
+			return current_node->xmlns;
+		} else if (current_node->namespace_map) {
+			const char *ns = g_hash_table_lookup(current_node->namespace_map, prefix);
+			if (ns && *ns) {
+				return ns;
+			}
+		}
+
+		current_node = current_node->parent;
+	}
+
+	return NULL;
+}
+
+void xmlnode_strip_prefixes(xmlnode *node)
+{
+	xmlnode *child;
+	const char *prefix;
+
+	g_return_if_fail(node != NULL);
+
+	for (child = node->child; child; child = child->next) {
+		if (child->type == XMLNODE_TYPE_TAG)
+			xmlnode_strip_prefixes(child);
+	}
+
+	prefix = xmlnode_get_prefix(node);
+	if (prefix) {
+		const char *ns = xmlnode_get_prefix_namespace(node, prefix);
+		xmlnode_set_namespace(node, ns);
+		xmlnode_set_prefix(node, NULL);
+	} else {
+		xmlnode_set_namespace(node, xmlnode_get_default_namespace(node));
+	}
+}
+
 xmlnode *xmlnode_get_parent(const xmlnode *child)
 {
 	g_return_val_if_fail(child != NULL, NULL);
@@ -455,12 +549,22 @@
 	if (node->namespace_map) {
 		g_hash_table_foreach(node->namespace_map,
 			(GHFunc)xmlnode_to_str_foreach_append_ns, text);
-	} else if (node->xmlns) {
-		if(!node->parent || !purple_strequal(node->xmlns, node->parent->xmlns))
+	} else {
+		/* Figure out if this node has a different default namespace from parent */
+		const char *xmlns = NULL;
+		const char *parent_xmlns = NULL;
+		if (!prefix)
+			xmlns = node->xmlns;
+
+		if (!xmlns)
+			xmlns = xmlnode_get_default_namespace(node);
+		if (node->parent)
+			parent_xmlns = xmlnode_get_default_namespace(node->parent);
+		if (!purple_strequal(xmlns, parent_xmlns))
 		{
-			char *xmlns = g_markup_escape_text(node->xmlns, -1);
-			g_string_append_printf(text, " xmlns='%s'", xmlns);
-			g_free(xmlns);
+			char *escaped_xmlns = g_markup_escape_text(xmlns, -1);
+			g_string_append_printf(text, " xmlns='%s'", escaped_xmlns);
+			g_free(escaped_xmlns);
 		}
 	}
 	for(c = node->child; c; c = c->next)
@@ -648,10 +752,23 @@
 static void
 xmlnode_parser_structural_error_libxml(void *user_data, xmlErrorPtr error)
 {
+	// On Mac OS X 10.8 libxml2 will call this function with user_data == NULL
+	// if xmlSetStructuredErrorFunc was set. Use this as a workaround.
+	// http://trac.adium.im/ticket/16095
+	
 	struct _xmlnode_parser_data *xpd = user_data;
 
+	if (error && !xpd) {
+		xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)error->ctxt;
+		
+		if (ctxt) {
+			xpd = ctxt->userData;
+		}
+	}
+
 	if (error && (error->level == XML_ERR_ERROR ||
-	              error->level == XML_ERR_FATAL)) {
+	              error->level == XML_ERR_FATAL)
+		&& xpd) {
 		xpd->error = TRUE;
 		purple_debug_error("xmlnode", "XML parser error for xmlnode %p: "
 		                   "Domain %i, code %i, level %i: %s",
diff -r fb9fe934688e -r eafc92ac5f87 libpurple/xmlnode.h
--- a/libpurple/xmlnode.h	Thu Sep 27 00:23:57 2012 -0400
+++ b/libpurple/xmlnode.h	Wed Oct 17 14:17:21 2012 +0200
@@ -249,7 +249,35 @@
  * @param node The node to get the namepsace from
  * @return The namespace of this node
  */
-const char *xmlnode_get_namespace(xmlnode *node);
+const char *xmlnode_get_namespace(const xmlnode *node);
+
+/**
+ * Returns the current default namespace.  The default
+ * namespace is the current namespace which applies to child
+ * elements which are unprefixed and which do not contain their
+ * own namespace.
+ *
+ * For example, given:
+ * <iq type='get' xmlns='jabber:client' xmlns:ns1='http://example.org/ns1'>
+ *     <ns1:element><child1/></ns1:element>
+ * </iq>
+ *
+ * The default namespace of all nodes (including 'child1') is "jabber:client",
+ * though the namespace for 'element' is "http://example.org/ns1".
+ *
+ * @param node The node for which to return the default namespace
+ * @return The default namespace of this node
+ */
+const char *xmlnode_get_default_namespace(const xmlnode *node);
+
+/**
+ * Returns the defined namespace for a prefix.
+ *
+ * @param node The node from which to start the search.
+ * @param prefix The prefix for which to return the associated namespace.
+ * @return The namespace for this prefix.
+ */
+const char *xmlnode_get_prefix_namespace(const xmlnode *node, const char *prefix);
 
 /**
  * Sets the prefix of a node
@@ -268,6 +296,19 @@
 const char *xmlnode_get_prefix(const xmlnode *node);
 
 /**
+ * Remove all element prefixes from an xmlnode tree.  The prefix's
+ * namespace is transformed into the default namespace for an element.
+ *
+ * Note that this will not necessarily remove all prefixes in use
+ * (prefixed attributes may still exist), and that this usage may
+ * break some applications (SOAP / XPath apparently often rely on
+ * the prefixes having the same name.
+ *
+ * @param node The node from which to strip prefixes
+ */
+void xmlnode_strip_prefixes(xmlnode *node);
+
+/**
  * Gets the parent node.
  *
  * @param child The child node.
diff -r fb9fe934688e -r eafc92ac5f87 pidgin/win32/nsis/generate_gtk_zip.sh
--- a/pidgin/win32/nsis/generate_gtk_zip.sh	Thu Sep 27 00:23:57 2012 -0400
+++ b/pidgin/win32/nsis/generate_gtk_zip.sh	Wed Oct 17 14:17:21 2012 +0200
@@ -2,6 +2,7 @@
 # Script to generate zip file for GTK+ runtime to be included in Pidgin installer
 
 PIDGIN_BASE=$1
+GPG_SIGN=$2
 
 if [ ! -e $PIDGIN_BASE/ChangeLog ]; then
 	echo $(basename $0) must must have the pidgin base dir specified as a parameter.
@@ -12,9 +13,32 @@
 #Subdirectory of $STAGE_DIR
 INSTALL_DIR=Gtk
 CONTENTS_FILE=$INSTALL_DIR/CONTENTS
+PIDGIN_VERSION=$( < $PIDGIN_BASE/VERSION )
 
 #This needs to be changed every time there is any sort of change.
 BUNDLE_VERSION=2.16.6.1
+BUNDLE_SHA1SUM=5e16b7efb11943e8c80bc390f6c38df904fd36ed
+ZIP_FILE="$PIDGIN_BASE/pidgin/win32/nsis/gtk-runtime-$BUNDLE_VERSION.zip"
+
+#Download the existing file (so that we distribute the exact same file for all releases with the same bundle version)
+FILE="$ZIP_FILE"
+if [ ! -e "$FILE" ]; then
+	wget "https://pidgin.im/win32/download_redir.php?version=$PIDGIN_VERSION&gtk_version=$BUNDLE_VERSION&dl_pkg=gtk" -O "$FILE"
+fi
+CHECK_SHA1SUM=`sha1sum $FILE`
+CHECK_SHA1SUM=${CHECK_SHA1SUM%%\ *}
+if [ "$CHECK_SHA1SUM" != "$BUNDLE_SHA1SUM" ]; then
+	echo "sha1sum ($CHECK_SHA1SUM) for $FILE doesn't match expected value of $BUNDLE_SHA1SUM"
+	# Allow "devel" versions to build their own bundles if the download doesn't succeed
+	if [[ "$PIDGIN_VERSION" == *"devel" ]]; then
+		echo "Continuing GTK+ Bundle creation for development version of Pidgin"
+	else
+		exit 1
+	fi
+else
+	exit 0
+fi
+
 
 ATK="http://ftp.gnome.org/pub/gnome/binaries/win32/atk/1.32/atk_1.32.0-2_win32.zip ATK 1.32.0-2 sha1sum:3c31c9d6b19af840e2bd8ccbfef4072a6548dc4e"
 #Cairo 1.10.2 has a bug that can be seen when selecting text
@@ -66,12 +90,14 @@
 			wget "$URL.asc" || exit 1
 		fi
 		#Use our own keyring to avoid adding stuff to the main keyring
-		GPG="gpg -q --keyring $VALIDATION_VALUE-keyring.gpg"
-		$GPG --list-keys "$VALIDATION_VALUE" > /dev/null
-		if [ $? -ne 0 ]; then
-		       	$GPG --keyserver pgp.mit.edu --recv-key "$VALIDATION_VALUE" || exit 1
+		#This doesn't use $GPG_SIGN because we don't this validation to be bypassed when people are skipping signing output
+		GPG_BASE="gpg -q --keyring $STAGE_DIR/$VALIDATION_VALUE-keyring.gpg" 
+		if [[ ! -e $STAGE_DIR/$VALIDATION_VALUE-keyring.gpg \
+				|| `$GPG_BASE --list-keys "$VALIDATION_VALUE" > /dev/null && echo -n "0"` -ne 0 ]]; then
+			touch $STAGE_DIR/$VALIDATION_VALUE-keyring.gpg
+		       	$GPG_BASE --no-default-keyring --keyserver pgp.mit.edu --recv-key "$VALIDATION_VALUE" || exit 1
 		fi
-		$GPG --verify "$FILE.asc" || (echo "$FILE failed signature verification"; exit 1) || exit 1
+		$GPG_BASE --verify "$FILE.asc" || (echo "$FILE failed signature verification"; exit 1) || exit 1
 	else
 		echo "Unrecognized validation type of $VALIDATION_TYPE"
 		exit 1
@@ -106,9 +132,9 @@
 done
 
 #Generate zip file to be included in installer
-ZIPFILE=../gtk-runtime-$BUNDLE_VERSION.zip
-rm -f $ZIPFILE
-zip -9 -r $ZIPFILE Gtk
+rm -f $ZIP_FILE
+zip -9 -r $ZIP_FILE Gtk
+($GPG_SIGN -ab $ZIP_FILE && $GPG_SIGN --verify $ZIP_FILE.asc) || exit 1
 
 exit 0
 
diff -r fb9fe934688e -r eafc92ac5f87 pidgin/win32/nsis/pidgin-installer.nsi
--- a/pidgin/win32/nsis/pidgin-installer.nsi	Thu Sep 27 00:23:57 2012 -0400
+++ b/pidgin/win32/nsis/pidgin-installer.nsi	Wed Oct 17 14:17:21 2012 +0200
@@ -255,27 +255,22 @@
 !else




More information about the commits mailing list