|
15 | 15 | except ImportError:
|
16 | 16 | ssl = None
|
17 | 17 |
|
| 18 | +from test.test_urllib import FakeHTTPMixin |
| 19 | + |
| 20 | + |
18 | 21 | # XXX
|
19 | 22 | # Request
|
20 | 23 | # CacheFTPHandler (hard to write)
|
@@ -1262,7 +1265,7 @@ def _test_basic_auth(self, opener, auth_handler, auth_header,
|
1262 | 1265 | self.assertEqual(len(http_handler.requests), 1)
|
1263 | 1266 | self.assertFalse(http_handler.requests[0].has_header(auth_header))
|
1264 | 1267 |
|
1265 |
| -class MiscTests(unittest.TestCase): |
| 1268 | +class MiscTests(unittest.TestCase, FakeHTTPMixin): |
1266 | 1269 |
|
1267 | 1270 | def test_build_opener(self):
|
1268 | 1271 | class MyHTTPHandler(urllib2.HTTPHandler): pass
|
@@ -1317,6 +1320,52 @@ def test_unsupported_algorithm(self):
|
1317 | 1320 | "Unsupported digest authentication algorithm 'invalid'"
|
1318 | 1321 | )
|
1319 | 1322 |
|
| 1323 | + @unittest.skipUnless(ssl, "ssl module required") |
| 1324 | + def test_url_with_control_char_rejected(self): |
| 1325 | + for char_no in range(0, 0x21) + range(0x7f, 0x100): |
| 1326 | + char = chr(char_no) |
| 1327 | + schemeless_url = "//localhost:7777/test%s/" % char |
| 1328 | + self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") |
| 1329 | + try: |
| 1330 | + # We explicitly test urllib.request.urlopen() instead of the top |
| 1331 | + # level 'def urlopen()' function defined in this... (quite ugly) |
| 1332 | + # test suite. They use different url opening codepaths. Plain |
| 1333 | + # urlopen uses FancyURLOpener which goes via a codepath that |
| 1334 | + # calls urllib.parse.quote() on the URL which makes all of the |
| 1335 | + # above attempts at injection within the url _path_ safe. |
| 1336 | + escaped_char_repr = repr(char).replace('\\', r'\\') |
| 1337 | + InvalidURL = httplib.InvalidURL |
| 1338 | + with self.assertRaisesRegexp( |
| 1339 | + InvalidURL, "contain control.*" + escaped_char_repr): |
| 1340 | + urllib2.urlopen("http:" + schemeless_url) |
| 1341 | + with self.assertRaisesRegexp( |
| 1342 | + InvalidURL, "contain control.*" + escaped_char_repr): |
| 1343 | + urllib2.urlopen("https:" + schemeless_url) |
| 1344 | + finally: |
| 1345 | + self.unfakehttp() |
| 1346 | + |
| 1347 | + @unittest.skipUnless(ssl, "ssl module required") |
| 1348 | + def test_url_with_newline_header_injection_rejected(self): |
| 1349 | + self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") |
| 1350 | + host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123" |
| 1351 | + schemeless_url = "//" + host + ":8080/test/?test=a" |
| 1352 | + try: |
| 1353 | + # We explicitly test urllib2.urlopen() instead of the top |
| 1354 | + # level 'def urlopen()' function defined in this... (quite ugly) |
| 1355 | + # test suite. They use different url opening codepaths. Plain |
| 1356 | + # urlopen uses FancyURLOpener which goes via a codepath that |
| 1357 | + # calls urllib.parse.quote() on the URL which makes all of the |
| 1358 | + # above attempts at injection within the url _path_ safe. |
| 1359 | + InvalidURL = httplib.InvalidURL |
| 1360 | + with self.assertRaisesRegexp( |
| 1361 | + InvalidURL, r"contain control.*\\r.*(found at least . .)"): |
| 1362 | + urllib2.urlopen("http:" + schemeless_url) |
| 1363 | + with self.assertRaisesRegexp(InvalidURL, r"contain control.*\\n"): |
| 1364 | + urllib2.urlopen("https:" + schemeless_url) |
| 1365 | + finally: |
| 1366 | + self.unfakehttp() |
| 1367 | + |
| 1368 | + |
1320 | 1369 |
|
1321 | 1370 | class RequestTests(unittest.TestCase):
|
1322 | 1371 |
|
|
0 commit comments