Check for XML parsing errors and disconnect in that case.
This commit is contained in:
parent
df4012e66d
commit
6034df0a78
@ -19,7 +19,7 @@ import ssl
|
|||||||
import weakref
|
import weakref
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import xml.etree.ElementTree
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
from slixmpp.xmlstream.asyncio import asyncio
|
from slixmpp.xmlstream.asyncio import asyncio
|
||||||
from slixmpp.xmlstream import tostring, highlight
|
from slixmpp.xmlstream import tostring, highlight
|
||||||
@ -339,7 +339,7 @@ class XMLStream(asyncio.BaseProtocol):
|
|||||||
"""
|
"""
|
||||||
self.xml_depth = 0
|
self.xml_depth = 0
|
||||||
self.xml_root = None
|
self.xml_root = None
|
||||||
self.parser = xml.etree.ElementTree.XMLPullParser(("start", "end"))
|
self.parser = ET.XMLPullParser(("start", "end"))
|
||||||
|
|
||||||
def connection_made(self, transport):
|
def connection_made(self, transport):
|
||||||
"""Called when the TCP connection has been established with the server
|
"""Called when the TCP connection has been established with the server
|
||||||
@ -359,34 +359,46 @@ class XMLStream(asyncio.BaseProtocol):
|
|||||||
the stream is opened, etc).
|
the stream is opened, etc).
|
||||||
"""
|
"""
|
||||||
self.parser.feed(data)
|
self.parser.feed(data)
|
||||||
for event, xml in self.parser.read_events():
|
try:
|
||||||
if event == 'start':
|
for event, xml in self.parser.read_events():
|
||||||
if self.xml_depth == 0:
|
if event == 'start':
|
||||||
# We have received the start of the root element.
|
if self.xml_depth == 0:
|
||||||
self.xml_root = xml
|
# We have received the start of the root element.
|
||||||
log.debug('[33;1mRECV[0m: %s',
|
self.xml_root = xml
|
||||||
highlight(tostring(self.xml_root,
|
log.debug('[33;1mRECV[0m: %s',
|
||||||
xmlns=self.default_ns,
|
highlight(tostring(self.xml_root,
|
||||||
stream=self,
|
xmlns=self.default_ns,
|
||||||
top_level=True,
|
stream=self,
|
||||||
open_only=True)))
|
top_level=True,
|
||||||
self.start_stream_handler(self.xml_root)
|
open_only=True)))
|
||||||
self.xml_depth += 1
|
self.start_stream_handler(self.xml_root)
|
||||||
if event == 'end':
|
self.xml_depth += 1
|
||||||
self.xml_depth -= 1
|
if event == 'end':
|
||||||
if self.xml_depth == 0:
|
self.xml_depth -= 1
|
||||||
# The stream's root element has closed,
|
if self.xml_depth == 0:
|
||||||
# terminating the stream.
|
# The stream's root element has closed,
|
||||||
log.debug("End of stream received")
|
# terminating the stream.
|
||||||
self.abort()
|
log.debug("End of stream received")
|
||||||
elif self.xml_depth == 1:
|
self.abort()
|
||||||
# A stanza is an XML element that is a direct child of
|
elif self.xml_depth == 1:
|
||||||
# the root element, hence the check of depth == 1
|
# A stanza is an XML element that is a direct child of
|
||||||
self._spawn_event(xml)
|
# the root element, hence the check of depth == 1
|
||||||
if self.xml_root is not None:
|
self._spawn_event(xml)
|
||||||
# Keep the root element empty of children to
|
if self.xml_root is not None:
|
||||||
# save on memory use.
|
# Keep the root element empty of children to
|
||||||
self.xml_root.clear()
|
# save on memory use.
|
||||||
|
self.xml_root.clear()
|
||||||
|
except ET.ParseError:
|
||||||
|
log.error('Parse error: %r', data)
|
||||||
|
|
||||||
|
# Due to cyclic dependencies, this can’t be imported at the module
|
||||||
|
# level.
|
||||||
|
from slixmpp.stanza.stream_error import StreamError
|
||||||
|
error = StreamError()
|
||||||
|
error['condition'] = 'not-well-formed'
|
||||||
|
error['text'] = 'Server sent: %r' % data
|
||||||
|
self.send(error)
|
||||||
|
self.disconnect()
|
||||||
|
|
||||||
def is_connected(self):
|
def is_connected(self):
|
||||||
return self.transport is not None
|
return self.transport is not None
|
||||||
|
Loading…
Reference in New Issue
Block a user