diff --git a/ncclient/transport/third_party/junos/parser.py b/ncclient/transport/third_party/junos/parser.py index 22944079..d39c6685 100644 --- a/ncclient/transport/third_party/junos/parser.py +++ b/ncclient/transport/third_party/junos/parser.py @@ -51,6 +51,12 @@ def parse(self, data): self.sax_parser.feed(data) except SAXParseException: self._delimiter_check(data) + except SAXFilterXMLNotFoundError: + self.logger.debug('Missing SAX filter_xml. Switching from sax to dom parsing') + self._session.parser = DefaultXMLParser(self._session) + if not isinstance(data, bytes): + data = str.encode(data) + self._session._buffer.write(data) finally: self._parse10() @@ -262,5 +268,5 @@ def _write_buffer(self, content, format_str, **kwargs): for (name, value) in kwargs.items(): attr = ' {}={}'.format(name, quoteattr(value)) attrs = attrs + attr - data = format_str.format(content, attrs) + data = format_str.format(escape(content), attrs) self._session._buffer.write(str.encode(data)) diff --git a/test/unit/transport/test_parser.py b/test/unit/transport/test_parser.py index dd22ed1c..2156b397 100644 --- a/test/unit/transport/test_parser.py +++ b/test/unit/transport/test_parser.py @@ -109,6 +109,92 @@ def test_filter_xml_delimiter_multiple_rpc_reply(self, mock_uuid4, mock_select, self.assertEqual(len(resp.xpath('multi-routing-engine-item/re-name')), 2) self.assertEqual(len(resp.xpath('multi-routing-engine-item/software-information')), 0) + @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") + @patch('ncclient.transport.SSHSession.connected') + @patch('paramiko.channel.Channel.send_ready') + @patch('paramiko.channel.Channel.send') + @patch('ncclient.transport.ssh.SSHSession.close') + @patch('paramiko.channel.Channel.recv') + @patch('ncclient.transport.SSHSession') + @patch('selectors.DefaultSelector.select') + @patch('ncclient.operations.rpc.uuid4') + def test_filter_xml_delimiter_multiple_rpc_in_parallel(self, mock_uuid4, mock_select, + mock_session, mock_recv, mock_close, + mock_send, mock_send_ready, + mock_connected): + mock_send.return_value = True + mock_send_ready.return_value = -1 + mock_uuid4.side_effect = [type('xyz', (), {'urn': "urn:uuid:ddef40cb-5745-481d-974d-7188f9f2bb33"}), + type('pqr', (), {'urn': "urn:uuid:549ef9d1-024a-4fd0-88bf-047d25f0870d"})] + device_handler = manager.make_device_handler({'name': 'junos', 'use_filter': True}) + rpc = '' + mock_recv.side_effect = [b""" + + + + 13.1.1.2 + ge-0/0/0.1 + Exchange + 2.2.2.2 + 128 + 36 + 0.0.0.0 + 0x52 + 13.1.1.1 + 13.1.1.2 + + 04:56:52 + + + 04:56:52 + + slave + 0x204b6fd + 3 + 0 + + Link state retransmission list: + Type LSA ID Adv rtr Seq + Router 1.1.1.1 1.1.1.1 0x80000019 + OpaqArea 1.0.0.1 1.1.1.1 0x80000011 + Router 3.3.3.3 3.3.3.3 0x80000004 + Network 23.1.1.2 3.3.3.3 0x80000001 + OpaqArea 1.0.0.1 2.2.2.2 0x80000002 + OpaqArea 1.0.0.1 3.3.3.3 0x80000002 + OpaqArea 1.0.0.3 1.1.1.1 0x80000002 + OpaqArea 1.0.0.3 3.3.3.3 0x80000001 + OpaqArea 1.0.0.4 2.2.2.2 0x80000001 + + + default + 0 + Forward Only + + + + ]]>]]> + + + 22450 + 0 + 31992 + 0 + 0 + 0 + 0 + 0 + ]]>]]>"""] + session = SSHSession(device_handler) + session._connected = True + session._channel = paramiko.Channel("c100") + session.parser = session._device_handler.get_xml_parser(session) + obj = ExecuteRpc(session, device_handler, raise_mode=RaiseMode.ALL) + obj = ExecuteRpc(session, device_handler, raise_mode=RaiseMode.ALL) + obj._filter_xml = '' + session.run() + resp = obj.request(rpc)._NCElement__doc[0] + self.assertEqual(len(resp.xpath('pfe-traffic-statistics')), 1) + @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") @patch('ncclient.transport.SSHSession.connected') @patch('paramiko.channel.Channel.send_ready')