|
3 | 3 | from datetime import datetime
|
4 | 4 | from unittest import mock
|
5 | 5 |
|
| 6 | +from django.core.exceptions import TooManyFieldsSent |
6 | 7 | from django.test import SimpleTestCase, ignore_warnings
|
7 | 8 | from django.utils.datastructures import MultiValueDict
|
8 | 9 | from django.utils.deprecation import RemovedInDjango40Warning
|
9 | 10 | from django.utils.http import (
|
10 | 11 | base36_to_int, escape_leading_slashes, http_date, int_to_base36,
|
11 |
| - is_safe_url, is_same_domain, parse_etags, parse_http_date, quote_etag, |
12 |
| - url_has_allowed_host_and_scheme, urlencode, urlquote, urlquote_plus, |
13 |
| - urlsafe_base64_decode, urlsafe_base64_encode, urlunquote, urlunquote_plus, |
| 12 | + is_safe_url, is_same_domain, limited_parse_qsl, parse_etags, |
| 13 | + parse_http_date, quote_etag, url_has_allowed_host_and_scheme, urlencode, |
| 14 | + urlquote, urlquote_plus, urlsafe_base64_decode, urlsafe_base64_encode, |
| 15 | + urlunquote, urlunquote_plus, |
14 | 16 | )
|
15 | 17 |
|
16 | 18 |
|
@@ -359,3 +361,47 @@ def test(self):
|
359 | 361 | for url, expected in tests:
|
360 | 362 | with self.subTest(url=url):
|
361 | 363 | self.assertEqual(escape_leading_slashes(url), expected)
|
| 364 | + |
| 365 | + |
| 366 | +# Backport of unit tests for urllib.parse.parse_qsl() from Python 3.8.8. |
| 367 | +# Copyright (C) 2021 Python Software Foundation (see LICENSE.python). |
| 368 | +class ParseQSLBackportTests(unittest.TestCase): |
| 369 | + def test_parse_qsl(self): |
| 370 | + tests = [ |
| 371 | + ('', []), |
| 372 | + ('&', []), |
| 373 | + ('&&', []), |
| 374 | + ('=', [('', '')]), |
| 375 | + ('=a', [('', 'a')]), |
| 376 | + ('a', [('a', '')]), |
| 377 | + ('a=', [('a', '')]), |
| 378 | + ('&a=b', [('a', 'b')]), |
| 379 | + ('a=a+b&b=b+c', [('a', 'a b'), ('b', 'b c')]), |
| 380 | + ('a=1&a=2', [('a', '1'), ('a', '2')]), |
| 381 | + (';a=b', [(';a', 'b')]), |
| 382 | + ('a=a+b;b=b+c', [('a', 'a b;b=b c')]), |
| 383 | + ] |
| 384 | + for original, expected in tests: |
| 385 | + with self.subTest(original): |
| 386 | + result = limited_parse_qsl(original, keep_blank_values=True) |
| 387 | + self.assertEqual(result, expected, 'Error parsing %r' % original) |
| 388 | + expect_without_blanks = [v for v in expected if len(v[1])] |
| 389 | + result = limited_parse_qsl(original, keep_blank_values=False) |
| 390 | + self.assertEqual(result, expect_without_blanks, 'Error parsing %r' % original) |
| 391 | + |
| 392 | + def test_parse_qsl_encoding(self): |
| 393 | + result = limited_parse_qsl('key=\u0141%E9', encoding='latin-1') |
| 394 | + self.assertEqual(result, [('key', '\u0141\xE9')]) |
| 395 | + result = limited_parse_qsl('key=\u0141%C3%A9', encoding='utf-8') |
| 396 | + self.assertEqual(result, [('key', '\u0141\xE9')]) |
| 397 | + result = limited_parse_qsl('key=\u0141%C3%A9', encoding='ascii') |
| 398 | + self.assertEqual(result, [('key', '\u0141\ufffd\ufffd')]) |
| 399 | + result = limited_parse_qsl('key=\u0141%E9-', encoding='ascii') |
| 400 | + self.assertEqual(result, [('key', '\u0141\ufffd-')]) |
| 401 | + result = limited_parse_qsl('key=\u0141%E9-', encoding='ascii', errors='ignore') |
| 402 | + self.assertEqual(result, [('key', '\u0141-')]) |
| 403 | + |
| 404 | + def test_parse_qsl_field_limit(self): |
| 405 | + with self.assertRaises(TooManyFieldsSent): |
| 406 | + limited_parse_qsl('&'.join(['a=a'] * 11), fields_limit=10) |
| 407 | + limited_parse_qsl('&'.join(['a=a'] * 10), fields_limit=10) |
0 commit comments