You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.6 KiB
144 lines
4.6 KiB
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.<strong>add</strong>, 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<script>') |
|
+ self.serv.set_server_documentation('test_documentation<script>') |
|
+ self.assertEqual('test_title<script>', self.serv.server_title) |
|
+ self.assertEqual('test_documentation<script>', |
|
+ self.serv.server_documentation) |
|
+ |
|
+ generated = self.serv.generate_html_documentation() |
|
+ title = re.search(r'<title>(.+?)</title>', generated).group() |
|
+ documentation = re.search(r'<p><tt>(.+?)</tt></p>', generated).group() |
|
+ self.assertEqual('<title>Python: test_title<script></title>', |
|
+ title) |
|
+ self.assertEqual('<p><tt>test_documentation<script></tt></p>', |
|
+ documentation) |
|
+ |
|
+ |
|
def test_main(): |
|
test_support.run_unittest(DocXMLRPCHTTPGETServer) |
|
|
|
|