diff --git a/SOURCES/00344-CVE-2019-16935.patch b/SOURCES/00344-CVE-2019-16935.patch new file mode 100644 index 0000000..86d192f --- /dev/null +++ b/SOURCES/00344-CVE-2019-16935.patch @@ -0,0 +1,144 @@ +diff --git a/Lib/DocXMLRPCServer.py b/Lib/DocXMLRPCServer.py +index 4064ec2..90b037d 100644 +--- a/Lib/DocXMLRPCServer.py ++++ b/Lib/DocXMLRPCServer.py +@@ -20,6 +20,16 @@ from SimpleXMLRPCServer import (SimpleXMLRPCServer, + CGIXMLRPCRequestHandler, + resolve_dotted_attribute) + ++ ++def _html_escape_quote(s): ++ s = s.replace("&", "&") # Must be done first! ++ s = s.replace("<", "<") ++ s = s.replace(">", ">") ++ s = s.replace('"', """) ++ s = s.replace('\'', "'") ++ return s ++ ++ + class ServerHTMLDoc(pydoc.HTMLDoc): + """Class used to generate pydoc HTML document for a server""" + +@@ -210,7 +220,8 @@ class XMLRPCDocGenerator: + methods + ) + +- return documenter.page(self.server_title, documentation) ++ title = _html_escape_quote(self.server_title) ++ return documenter.page(title, documentation) + + class DocXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): + """XML-RPC and documentation request handler class. +diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py +index 80d1803..d464ef8 100644 +--- a/Lib/test/test_docxmlrpc.py ++++ b/Lib/test/test_docxmlrpc.py +@@ -1,13 +1,11 @@ + from DocXMLRPCServer import DocXMLRPCServer + import httplib ++import re + import sys + from test import test_support + threading = test_support.import_module('threading') +-import time +-import socket + import unittest + +-PORT = None + + def make_request_and_skipIf(condition, reason): + # If we skip the test, we have to make a request because the +@@ -23,13 +21,10 @@ def make_request_and_skipIf(condition, reason): + return decorator + + +-def server(evt, numrequests): ++def make_server(): + serv = DocXMLRPCServer(("localhost", 0), logRequests=False) + + try: +- global PORT +- PORT = serv.socket.getsockname()[1] +- + # Add some documentation + serv.set_server_title("DocXMLRPCServer Test Documentation") + serv.set_server_name("DocXMLRPCServer Test Docs") +@@ -56,42 +51,31 @@ def server(evt, numrequests): + + serv.register_function(add) + serv.register_function(lambda x, y: x-y) +- +- while numrequests > 0: +- serv.handle_request() +- numrequests -= 1 +- except socket.timeout: +- pass +- finally: ++ return serv ++ except: + serv.server_close() +- PORT = None +- evt.set() ++ raise + + class DocXMLRPCHTTPGETServer(unittest.TestCase): + def setUp(self): +- self._threads = test_support.threading_setup() + # Enable server feedback + DocXMLRPCServer._send_traceback_header = True + +- self.evt = threading.Event() +- threading.Thread(target=server, args=(self.evt, 1)).start() +- +- # wait for port to be assigned +- n = 1000 +- while n > 0 and PORT is None: +- time.sleep(0.001) +- n -= 1 ++ self.serv = make_server() ++ self.thread = threading.Thread(target=self.serv.serve_forever) ++ self.thread.start() + ++ PORT = self.serv.server_address[1] + self.client = httplib.HTTPConnection("localhost:%d" % PORT) + + def tearDown(self): + self.client.close() + +- self.evt.wait() +- + # Disable server feedback + DocXMLRPCServer._send_traceback_header = False +- test_support.threading_cleanup(*self._threads) ++ self.serv.shutdown() ++ self.thread.join() ++ self.serv.server_close() + + def test_valid_get_response(self): + self.client.request("GET", "/") +@@ -194,6 +178,25 @@ class DocXMLRPCHTTPGETServer(unittest.TestCase): + self.assertIn("""Try self.add, too.""", + response.read()) + ++ def test_server_title_escape(self): ++ """Test that the server title and documentation ++ are escaped for HTML. ++ """ ++ self.serv.set_server_title('test_title