comparison test/test_xmlrpc.py @ 8237:57325fea9982

issue2551116 - Replace xmlrpclib (xmlrpc.client) with defusedxml. defusedxml will be used to moneypatch the problematic client and server modules. Test added using an xml bomb.
author John Rouillard <rouilj@ieee.org>
date Sun, 29 Dec 2024 19:11:01 -0500
parents 978285986b2c
children 05405220dc38
comparison
equal deleted inserted replaced
8236:2d0bd038fc5e 8237:57325fea9982
3 # All rights reserved. 3 # All rights reserved.
4 # For license terms see the file COPYING.txt. 4 # For license terms see the file COPYING.txt.
5 # 5 #
6 6
7 from __future__ import print_function 7 from __future__ import print_function
8 import unittest, os, shutil, errno, sys, difflib, re 8 import unittest, os, shutil, errno, pytest, sys, difflib, re
9 9
10 from roundup.anypy import xmlrpc_ 10 from roundup.anypy import xmlrpc_
11 MultiCall = xmlrpc_.client.MultiCall 11 MultiCall = xmlrpc_.client.MultiCall
12 from roundup.cgi.exceptions import * 12 from roundup.cgi.exceptions import *
13 from roundup import init, instance, password, hyperdb, date 13 from roundup import init, instance, password, hyperdb, date
19 19
20 from . import db_test_base 20 from . import db_test_base
21 from .test_mysql import skip_mysql 21 from .test_mysql import skip_mysql
22 from .test_postgresql import skip_postgresql 22 from .test_postgresql import skip_postgresql
23 23
24 from .pytest_patcher import mark_class
25 from roundup.anypy.xmlrpc_ import client
26
27 if client.defusedxml:
28 skip_defusedxml = lambda func, *args, **kwargs: func
29
30 skip_defusedxml_used = mark_class(pytest.mark.skip(
31 reason='Skipping non-defusedxml tests: defusedxml library in use'))
32 else:
33 skip_defusedxml = mark_class(pytest.mark.skip(
34 reason='Skipping defusedxml tests: defusedxml library not available'))
35
36 skip_defusedxml_used = lambda func, *args, **kwargs: func
24 37
25 class XmlrpcTest(object): 38 class XmlrpcTest(object):
26 39
27 backend = None 40 backend = None
28 41
312 'keyword': [], 'title': 'i2', 'nosy': [], 'messages': [], 325 'keyword': [], 'title': 'i2', 'nosy': [], 'messages': [],
313 'priority': None, 'assignedto': None, 'superseder': []}] 326 'priority': None, 'assignedto': None, 'superseder': []}]
314 for n, r in enumerate(result): 327 for n, r in enumerate(result):
315 self.assertEqual(r, results[n]) 328 self.assertEqual(r, results[n])
316 329
330 @skip_defusedxml
331 def testDefusedXmlBomb(self):
332 self.XmlBomb(expectIn=b"defusedxml.common.EntitiesForbidden")
333
334 @skip_defusedxml_used
335 def testNonDefusedXmlBomb(self):
336 self.XmlBomb(expectIn=b"1234567890"*511)
337
338 def XmlBomb(self, expectIn=None):
339
340 bombInput = """<?xml version='1.0'?>
341 <!DOCTYPE xmlbomb [
342 <!ENTITY a "1234567890" >
343 <!ENTITY b "&a;&a;&a;&a;&a;&a;&a;&a;">
344 <!ENTITY c "&b;&b;&b;&b;&b;&b;&b;&b;">
345 <!ENTITY d "&c;&c;&c;&c;&c;&c;&c;&c;">
346 ]>
347 <methodCall>
348 <methodName>filter</methodName>
349 <params>
350 <param>
351 <value><string>&d;</string></value>
352 </param>
353 <param>
354 <value><array><data>
355 <value><string>0</string></value>
356 <value><string>2</string></value>
357 <value><string>3</string></value>
358 </data></array></value>
359 </param>
360 <param>
361 <value><struct>
362 <member>
363 <name>username</name>
364 <value><string>demo</string></value>
365 </member>
366 </struct></value>
367 </param>
368 </params>
369 </methodCall>
370 """
371 translator = TranslationService.get_translation(
372 language=self.instance.config["TRACKER_LANGUAGE"],
373 tracker_home=self.instance.config["TRACKER_HOME"])
374 self.server = RoundupDispatcher(self.db, self.instance.actions,
375 translator, allow_none = True)
376 response = self.server.dispatch(bombInput)
377 print(response)
378 self.assertIn(expectIn, response)
317 379
318 class anydbmXmlrpcTest(XmlrpcTest, unittest.TestCase): 380 class anydbmXmlrpcTest(XmlrpcTest, unittest.TestCase):
319 backend = 'anydbm' 381 backend = 'anydbm'
320 382
321 383

Roundup Issue Tracker: http://roundup-tracker.org/