Merged revisions 71303 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r71303 | gregory.p.smith | 2009-04-06 01:33:26 -0500 (Mon, 06 Apr 2009) | 3 lines

  - Issue #2254: Fix CGIHTTPServer information disclosure.  Relative paths are
    now collapsed within the url properly before looking in cgi_directories.
........
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
index 0305a90..837d4a6 100644
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -6,6 +6,7 @@
 
 from http.server import BaseHTTPRequestHandler, HTTPServer, \
      SimpleHTTPRequestHandler, CGIHTTPRequestHandler
+from http import server
 
 import os
 import sys
@@ -316,6 +317,45 @@
         finally:
             BaseTestCase.tearDown(self)
 
+    def test_url_collapse_path_split(self):
+        test_vectors = {
+            '': ('/', ''),
+            '..': IndexError,
+            '/.//..': IndexError,
+            '/': ('/', ''),
+            '//': ('/', ''),
+            '/\\': ('/', '\\'),
+            '/.//': ('/', ''),
+            'cgi-bin/file1.py': ('/cgi-bin', 'file1.py'),
+            '/cgi-bin/file1.py': ('/cgi-bin', 'file1.py'),
+            'a': ('/', 'a'),
+            '/a': ('/', 'a'),
+            '//a': ('/', 'a'),
+            './a': ('/', 'a'),
+            './C:/': ('/C:', ''),
+            '/a/b': ('/a', 'b'),
+            '/a/b/': ('/a/b', ''),
+            '/a/b/c/..': ('/a/b', ''),
+            '/a/b/c/../d': ('/a/b', 'd'),
+            '/a/b/c/../d/e/../f': ('/a/b/d', 'f'),
+            '/a/b/c/../d/e/../../f': ('/a/b', 'f'),
+            '/a/b/c/../d/e/.././././..//f': ('/a/b', 'f'),
+            '../a/b/c/../d/e/.././././..//f': IndexError,
+            '/a/b/c/../d/e/../../../f': ('/a', 'f'),
+            '/a/b/c/../d/e/../../../../f': ('/', 'f'),
+            '/a/b/c/../d/e/../../../../../f': IndexError,
+            '/a/b/c/../d/e/../../../../f/..': ('/', ''),
+        }
+        for path, expected in test_vectors.items():
+            if isinstance(expected, type) and issubclass(expected, Exception):
+                self.assertRaises(expected,
+                                  server._url_collapse_path_split, path)
+            else:
+                actual = server._url_collapse_path_split(path)
+                self.assertEquals(expected, actual,
+                                  msg='path = %r\nGot:    %r\nWanted: %r' % (
+                                  path, actual, expected))
+
     def test_headers_and_content(self):
         res = self.request('/cgi-bin/file1.py')
         self.assertEquals((b'Hello World\n', 'text/html', 200), \
@@ -341,6 +381,12 @@
         self.assertEquals((b'Hello World\n', 'text/html', 200), \
              (res.read(), res.getheader('Content-type'), res.status))
 
+    def test_no_leading_slash(self):
+        # http://bugs.python.org/issue2254
+        res = self.request('cgi-bin/file1.py')
+        self.assertEquals((b'Hello World\n', 'text/html', 200),
+             (res.read(), res.getheader('Content-type'), res.status))
+
 
 def test_main(verbose=None):
     try: