Index: gajim-0.14.4/src/common/connection_handlers.py =================================================================== --- gajim-0.14.4.orig/src/common/connection_handlers.py 2011-05-31 18:00:32.000000000 +0200 +++ gajim-0.14.4/src/common/connection_handlers.py 2011-10-23 19:52:10.679106710 +0200 @@ -1607,6 +1607,8 @@ if keyID: def decrypt_thread(encmsg, keyID): decmsg = self.gpg.decrypt(encmsg, keyID) + decmsg = self.connection.Dispatcher.replace_non_character( + decmsg) # \x00 chars are not allowed in C (so in GTK) msgtxt = helpers.decode_string(decmsg.replace('\x00', '')) encrypted = 'xep27' Index: gajim-0.14.4/src/common/stanza_session.py =================================================================== --- gajim-0.14.4.orig/src/common/stanza_session.py 2011-05-31 18:00:32.000000000 +0200 +++ gajim-0.14.4/src/common/stanza_session.py 2011-10-23 20:05:40.979105851 +0200 @@ -375,6 +375,12 @@ for child in parsed.getChildren(): stanza.addChild(node=child) + # replace non-character unicode + body = stanza.getBody() + if body: + stanza.setBody( + self.conn.connection.Dispatcher.replace_non_character(body)) + return stanza def decrypt(self, ciphertext): Index: gajim-0.14.4/src/common/xmpp/dispatcher_nb.py =================================================================== --- gajim-0.14.4.orig/src/common/xmpp/dispatcher_nb.py 2011-05-22 13:12:53.000000000 +0200 +++ gajim-0.14.4/src/common/xmpp/dispatcher_nb.py 2011-10-23 19:52:10.709106647 +0200 @@ -20,7 +20,7 @@ different handlers to different XMPP stanzas and namespaces """ -import simplexml, sys, locale +import re, simplexml, sys, locale from xml.parsers.expat import ExpatError from plugin import PlugIn from protocol import (NS_STREAMS, NS_XMPP_STREAMS, NS_HTTP_BIND, Iq, Presence, @@ -89,6 +89,24 @@ self.UnregisterHandler, self.RegisterProtocol, self.SendAndWaitForResponse, self.SendAndCallForResponse, self.getAnID, self.Event, self.send] + + # \ufddo -> \ufdef range + c = u'\ufdd0' + r = c.encode('utf8') + while (c < u'\ufdef'): + c = unichr(ord(c) + 1) + r += '|' + c.encode('utf8') + + # \ufffe-\uffff, \u1fffe-\u1ffff, ..., \u10fffe-\u10ffff + c = u'\ufffe' + r += '|' + c.encode('utf8') + r += '|' + unichr(ord(c) + 1).encode('utf8') + while (c < u'\U0010fffe'): + c = unichr(ord(c) + 0x10000) + r += '|' + c.encode('utf8') + r += '|' + unichr(ord(c) + 1).encode('utf8') + + self.invalid_chars_re = re.compile(r) def getAnID(self): global outgoingID @@ -174,6 +192,9 @@ raise ValueError('Incorrect stream start: (%s,%s). Terminating.' % (tag, ns)) + def replace_non_character(self, data): + return re.sub(self.invalid_chars_re, u'\ufffd'.encode('utf-8'), data) + def ProcessNonBlocking(self, data): """ Check incoming stream for data waiting @@ -189,6 +210,7 @@ # disconnect method will never be called. # Is this intended? # also look at transports start_disconnect() + data = self.replace_non_character(data) for handler in self._cycleHandlers: handler(self) if len(self._pendingExceptions) > 0: