]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-116764: Fix regressions in urllib.parse.parse_qsl() (GH-116801)
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 16 Mar 2024 10:36:05 +0000 (12:36 +0200)
committerGitHub <noreply@github.com>
Sat, 16 Mar 2024 10:36:05 +0000 (12:36 +0200)
* Restore support of None and other false values.
* Raise TypeError for non-zero integers and non-empty sequences.

The regressions were introduced in gh-74668
(bdba8ef42b15e651dc23374a08143cc2b4c4657d).

Lib/test/test_urlparse.py
Lib/urllib/parse.py
Misc/NEWS.d/next/Library/2024-03-14-14-01-46.gh-issue-116764.moB3Lc.rst [new file with mode: 0644]

index 72f028680f4cb5a38fdc6b02bbf5265fdebac6f9..236b6e4516490a1722fab8d0569ccfbf1c885870 100644 (file)
@@ -1072,6 +1072,30 @@ class UrlParseTestCase(unittest.TestCase):
                 result_bytes = urllib.parse.parse_qsl(orig, separator=b';')
                 self.assertEqual(result_bytes, expect, "Error parsing %r" % orig)
 
+    def test_parse_qsl_bytes(self):
+        self.assertEqual(urllib.parse.parse_qsl(b'a=b'), [(b'a', b'b')])
+        self.assertEqual(urllib.parse.parse_qsl(bytearray(b'a=b')), [(b'a', b'b')])
+        self.assertEqual(urllib.parse.parse_qsl(memoryview(b'a=b')), [(b'a', b'b')])
+
+    def test_parse_qsl_false_value(self):
+        kwargs = dict(keep_blank_values=True, strict_parsing=True)
+        for x in '', b'', None, 0, 0.0, [], {}, memoryview(b''):
+            self.assertEqual(urllib.parse.parse_qsl(x, **kwargs), [])
+            self.assertRaises(ValueError, urllib.parse.parse_qsl, x, separator=1)
+
+    def test_parse_qsl_errors(self):
+        self.assertRaises(TypeError, urllib.parse.parse_qsl, list(b'a=b'))
+        self.assertRaises(TypeError, urllib.parse.parse_qsl, iter(b'a=b'))
+        self.assertRaises(TypeError, urllib.parse.parse_qsl, 1)
+        self.assertRaises(TypeError, urllib.parse.parse_qsl, object())
+
+        for separator in '', b'', None, 0, 1, 0.0, 1.5:
+            with self.assertRaises(ValueError):
+                urllib.parse.parse_qsl('a=b', separator=separator)
+        with self.assertRaises(UnicodeEncodeError):
+            urllib.parse.parse_qsl(b'a=b', separator='\xa6')
+        with self.assertRaises(UnicodeDecodeError):
+            urllib.parse.parse_qsl('a=b', separator=b'\xa6')
 
     def test_urlencode_sequences(self):
         # Other tests incidentally urlencode things; test non-covered cases:
index ec52821125005c86b081a6db15b4aca116c581de..fc9e7c99f283bed2f9af4e8756268ae85fc6711b 100644 (file)
@@ -773,7 +773,11 @@ def parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
         def _unquote(s):
             return unquote_plus(s, encoding=encoding, errors=errors)
     else:
-        qs = bytes(qs)
+        if not qs:
+            return []
+        # Use memoryview() to reject integers and iterables,
+        # acceptable by the bytes constructor.
+        qs = bytes(memoryview(qs))
         if isinstance(separator, str):
             separator = bytes(separator, 'ascii')
         eq = b'='
diff --git a/Misc/NEWS.d/next/Library/2024-03-14-14-01-46.gh-issue-116764.moB3Lc.rst b/Misc/NEWS.d/next/Library/2024-03-14-14-01-46.gh-issue-116764.moB3Lc.rst
new file mode 100644 (file)
index 0000000..e92034b
--- /dev/null
@@ -0,0 +1,4 @@
+Restore support of ``None`` and other false values in :mod:`urllib.parse`
+functions :func:`~urllib.parse.parse_qs` and
+:func:`~urllib.parse.parse_qsl`. Also, they now raise a TypeError for
+non-zero integers and non-empty sequences.