]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-30566: Fix IndexError when using punycode codec (GH-18632)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 25 Feb 2020 03:43:46 +0000 (19:43 -0800)
committerGitHub <noreply@github.com>
Tue, 25 Feb 2020 03:43:46 +0000 (06:43 +0300)
Trying to decode an invalid string with the punycode codec
shoud raise UnicodeError.

(cherry picked from commit ba22e8f174309979d90047c5dc64fcb63bc2c32e)

Co-authored-by: Berker Peksag <berker.peksag@gmail.com>
Lib/encodings/punycode.py
Lib/test/test_codecs.py
Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst [new file with mode: 0644]

index 66c51013ea431ace41d4c7b20da8df3349dc834c..1c5726447077b1716e4fa772ff85345c54d441f2 100644 (file)
@@ -143,7 +143,7 @@ def decode_generalized_number(extended, extpos, bias, errors):
             digit = char - 22 # 0x30-26
         elif errors == "strict":
             raise UnicodeError("Invalid extended code point '%s'"
-                               % extended[extpos])
+                               % extended[extpos-1])
         else:
             return extpos, None
         t = T(j, bias)
index cd2761353490a63f01adf3e3bc7c0f10f9a19d04..5a450ebd9dc2bf4826ff18d3146b551d68e6f42d 100644 (file)
@@ -1406,6 +1406,18 @@ class PunycodeTest(unittest.TestCase):
             puny = puny.decode("ascii").encode("ascii")
             self.assertEqual(uni, puny.decode("punycode"))
 
+    def test_decode_invalid(self):
+        testcases = [
+            (b"xn--w&", "strict", UnicodeError()),
+            (b"xn--w&", "ignore", "xn-"),
+        ]
+        for puny, errors, expected in testcases:
+            with self.subTest(puny=puny, errors=errors):
+                if isinstance(expected, Exception):
+                    self.assertRaises(UnicodeError, puny.decode, "punycode", errors)
+                else:
+                    self.assertEqual(puny.decode("punycode", errors), expected)
+
 
 class UnicodeInternalTest(unittest.TestCase):
     @unittest.skipUnless(SIZEOF_WCHAR_T == 4, 'specific to 32-bit wchar_t')
diff --git a/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst b/Misc/NEWS.d/next/Library/2020-02-24-03-45-28.bpo-30566.qROxty.rst
new file mode 100644 (file)
index 0000000..c780633
--- /dev/null
@@ -0,0 +1,2 @@
+Fix :exc:`IndexError` when trying to decode an invalid string with punycode
+codec.