Ticket #14 (new defect)

Opened 3 years ago

Last modified 2 days ago

In certain cases pyxmpp eats exceptions

Reported by: http://openid.xmpp.za.net/grzyw@… Owned by: jajcus
Priority: major Component: pyxmpp
Keywords: Cc:

Description

xmlextra.endElement() eats exceptions, instead of letting them propagate.

While it's bad style to let exceptions get away from callbacks, it may happen and then errors don't get reported. In my case an unexpected UnicodeEncodeError? from pyxmpp code itself wasn't caught in my code, wreaked some havoc and vanished without a trace. Not a pleasant thing to debug.

Relevant part of a stack from my case to illustrate the issue:

  File "/home/karol/programowanie/pyxmpp/pyxmpp/xmlextra.py", line 214, in endElement
    self._handler.stanza(self._doc, node1)
  File "/home/karol/programowanie/pyxmpp/pyxmpp/streambase.py", line 401, in stanza
    self._process_node(node)
  File "/home/karol/programowanie/pyxmpp/pyxmpp/stream.py", line 107, in _process_node
    StreamBase._process_node(self,xmlnode)
  File "/home/karol/programowanie/pyxmpp/pyxmpp/streambase.py", line 710, in _process_node
    self.process_stanza(stanza)
  File "/home/karol/programowanie/pyxmpp/pyxmpp/stanzaprocessor.py", line 274, in process_stanza
    if self.process_message(stanza):
  File "/home/karol/programowanie/pyxmpp/pyxmpp/stanzaprocessor.py", line 209, in process_message
    return self.__try_handlers(self._message_handlers,"normal",stanza)
  File "/home/karol/programowanie/pyxmpp/pyxmpp/stanzaprocessor.py", line 185, in __try_handlers
    response = handler(stanza)
  File "/home/karol/programowanie/soc/tmp/jabberbot/xmppbot.py", line 372, in handle_message
    response = self.handle_internal_command(sender, command)
  File "/home/karol/programowanie/soc/tmp/jabberbot/xmppbot.py", line 402, in handle_internal_command
    self.send_search_form(sender)
  File "/home/karol/programowanie/soc/tmp/jabberbot/xmppbot.py", line 319, in send_search_form
    message.add_content(form)
  File "/home/karol/programowanie/pyxmpp/pyxmpp/stanza.py", line 303, in add_content
    content.as_xml(parent = self.xmlnode, doc = common_doc)
  File "/home/karol/programowanie/pyxmpp/pyxmpp/objects.py", line 91, in as_xml
    self.complete_xml_element(xmlnode, doc1)
  File "/home/karol/programowanie/pyxmpp/pyxmpp/jabber/dataforms.py", line 632, in complete_xml_element
    xmlnode.newTextChild(ns, "title", self.title)
  File "/usr/lib64/python2.3/site-packages/libxml2.py", line 3325, in newTextChild
    ret = libxml2mod.xmlNewTextChild(self._o, ns__o, name, content)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u015b' in position 2: ordinal not in range(128)

Attachments

xmlextra.py (16.4 KB) - added by roberto ostinelli 23 months ago.
suggested replacement for the xmlextra.py file
xmlextra.2.py (16.5 KB) - added by roberto ostinelli 23 months ago.
suggested replacement for the xmlextra.py file
xmlextra.3.py (16.5 KB) - added by roberto ostinelli 23 months ago.
suggested replacement for the xmlextra.py file

Change History

Changed 23 months ago by roberto ostinelli

suggested replacement for the xmlextra.py file

Changed 23 months ago by roberto ostinelli

i have rewritten the xmlextra.endElement() function so that it does not eat error propagation. the described behaviour resulted from the extensive use of 'finally' statements in error trapping.

please take this WITH CAUTION as i have not fully tested it, however it does seem to solve my issues.

anyone trying this out please let the community and jajcus if this can be officially set in the svn rep.

the rewritten function can be seen here below, and i have attached the complete file for your convenience.

        def endElement(self, tag):
            ""
            self._current+="</%s>" % (tag,)
            self._level -= 1
            if self._level > 1:
                return
            if self._level==1:
                xml=self._head+self._current+self._tail
                doc=libxml2.parseDoc(xml)
                try:
                    node = doc.getRootElement().children
                except:
                    doc.freeDoc()
                    return
                try:
                    node1 = node.docCopyNode(self._doc, 1)
                except:
                    del node
                    doc.freeDoc()
                    return
                try:
                    self._root.addChild(node1)
                except:
                    node1.unlinkNode()
                    node1.freeNode()
                    del node1
                    del node
                    doc.freeDoc()
                try:
                    self._handler.stanza(self._doc, node1)
                except:
                    node1.unlinkNode()
                    node1.freeNode()
                    del node1
                    del node
                    doc.freeDoc()
                    raise
                del node1
                del node
                doc.freeDoc()
            else:
                xml=self._head+self._tail
                doc=libxml2.parseDoc(xml)
                try:
                    self._handler.stream_end(self._doc)
                    self._doc.freeDoc()
                    self._doc = None
                    self._root = None
                finally:
                    doc.freeDoc()

Changed 23 months ago by roberto ostinelli

suggested replacement for the xmlextra.py file

Changed 23 months ago by roberto ostinelli

forgot a return statement

        def endElement(self, tag):
            ""
            self._current+="</%s>" % (tag,)
            self._level -= 1
            if self._level > 1:
                return
            if self._level==1:
                xml=self._head+self._current+self._tail
                doc=libxml2.parseDoc(xml)
                try:
                    node = doc.getRootElement().children
                except:
                    doc.freeDoc()
                    return
                try:
                    node1 = node.docCopyNode(self._doc, 1)
                except:
                    del node
                    doc.freeDoc()
                    return
                try:
                    self._root.addChild(node1)
                except:
                    node1.unlinkNode()
                    node1.freeNode()
                    del node1
                    del node
                    doc.freeDoc()
                    return
                try:
                    self._handler.stanza(self._doc, node1)
                except:
                    node1.unlinkNode()
                    node1.freeNode()
                    del node1
                    del node
                    doc.freeDoc()
                    raise
                del node1
                del node
                doc.freeDoc()
            else:
                xml=self._head+self._tail
                doc=libxml2.parseDoc(xml)
                try:
                    self._handler.stream_end(self._doc)
                    self._doc.freeDoc()
                    self._doc = None
                    self._root = None
                finally:
                    doc.freeDoc()

Changed 23 months ago by roberto ostinelli

suggested replacement for the xmlextra.py file

Changed 19 months ago by anonymous

I have tested with xmlextra.3.py, when the SASLAuthenticationFailed exception raised, it still can't work right. the exception was eation by xmlpaser. see the follow message:

File "C:\Python25\Lib\site-packages\pyxmpp\xmlextra.py", line 229, in endElement

self._handler.stanza(self._doc, node1)

File "C:\Python25\Lib\site-packages\pyxmpp\streambase.py", line 402, in stanza

self._process_node(node)

File "C:\Python25\Lib\site-packages\pyxmpp\stream.py", line 105, in _process_node

if self._process_node_sasl(xmlnode):

File "C:\Python25\lib\site-packages\pyxmpp\streamsasl.py", line 102, in _process_node_sasl

self._process_sasl_node(xmlnode)

File "C:\Python25\lib\site-packages\pyxmpp\streamsasl.py", line 121, in _process_sasl_node

ret=self._process_sasl_failure(xmlnode)

File "C:\Python25\lib\site-packages\pyxmpp\streamsasl.py", line 322, in _process_sasl_failure

raise SASLAuthenticationFailed,"SASL authentication failed"

pyxmpp.exceptions.SASLAuthenticationFailed: SASL authentication failed

Changed 14 months ago by anonymous

SASLAuthenticationFailed exception can be handled right in pyxmpp 1.0.1. I have tested it in win32 platform.

Add/Change #14 (In certain cases pyxmpp eats exceptions)

Author


E-mail address and user name can be saved in the Preferences.


Action
as new
 
Note: See TracTickets for help on using tickets.