]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-149144: Use decodeURIComponent() for UTF-8 support in js_output() (GH-149157)
authorSeth Larson <seth@python.org>
Thu, 14 May 2026 21:10:39 +0000 (16:10 -0500)
committerGitHub <noreply@github.com>
Thu, 14 May 2026 21:10:39 +0000 (23:10 +0200)
Lib/http/cookies.py
Lib/test/test_http_cookies.py

index 800a2c18e3fa41a7715c94e35198daabc61d4206..9a6f01dfb5e69a67ab74a86e4a6c6d1a3cf2d6ff 100644 (file)
@@ -391,21 +391,20 @@ class Morsel(dict):
     def __repr__(self):
         return '<%s: %s>' % (self.__class__.__name__, self.OutputString())
 
-
     def _js_output(self, attrs=None):
         """Internal implementation without deprecation warning."""
-        import base64
+        import urllib.parse
         # Print javascript
         output_string = self.OutputString(attrs)
         if _has_control_character(output_string):
             raise CookieError("Control characters are not allowed in cookies")
         # Base64-encode value to avoid template
         # injection in cookie values.
-        output_encoded = base64.b64encode(output_string.encode('utf-8')).decode("ascii")
+        output_encoded = urllib.parse.quote(output_string, safe='', encoding='utf-8')
         return """
         <script type="text/javascript">
         <!-- begin hiding
-        document.cookie = atob(\"%s\");
+        document.cookie = decodeURIComponent(\"%s\");
         // end hiding -->
         </script>
         """ % (output_encoded,)
index cde268e3241850906754b00b262b15abcc2bc2a2..d1df2ec42f0d146d2ebcd580ea3df7700629024c 100644 (file)
@@ -1,11 +1,11 @@
 # Simple test suite for http/cookies.py
-import base64
 import copy
 import unittest
 import doctest
 from http import cookies
 import pickle
 from test import support
+import urllib.parse
 
 
 class CookieTests(unittest.TestCase):
@@ -152,21 +152,21 @@ class CookieTests(unittest.TestCase):
 
         self.assertEqual(C.output(['path']),
             'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
-        cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme; Version=1').decode('ascii')
+        cookie_encoded = urllib.parse.quote('Customer="WILE_E_COYOTE"; Path=/acme; Version=1', safe='', encoding='utf-8')
         with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
             self.assertEqual(C.js_output(), fr"""
         <script type="text/javascript">
         <!-- begin hiding
-        document.cookie = atob("{cookie_encoded}");
+        document.cookie = decodeURIComponent("{cookie_encoded}");
         // end hiding -->
         </script>
         """)
-        cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme').decode('ascii')
+        cookie_encoded = urllib.parse.quote('Customer="WILE_E_COYOTE"; Path=/acme', safe='', encoding='utf-8')
         with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
             self.assertEqual(C.js_output(['path']), fr"""
         <script type="text/javascript">
         <!-- begin hiding
-        document.cookie = atob("{cookie_encoded}");
+        document.cookie = decodeURIComponent("{cookie_encoded}");
         // end hiding -->
         </script>
         """)
@@ -271,21 +271,21 @@ class CookieTests(unittest.TestCase):
 
         self.assertEqual(C.output(['path']),
                          'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
-        expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1').decode('ascii')
+        expected_encoded_cookie = urllib.parse.quote('Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1', safe='', encoding='utf-8')
         with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
             self.assertEqual(C.js_output(), fr"""
         <script type="text/javascript">
         <!-- begin hiding
-        document.cookie = atob("{expected_encoded_cookie}");
+        document.cookie = decodeURIComponent("{expected_encoded_cookie}");
         // end hiding -->
         </script>
         """)
-        expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme').decode('ascii')
+        expected_encoded_cookie = urllib.parse.quote('Customer=\"WILE_E_COYOTE\"; Path=/acme', safe='', encoding='utf-8')
         with self.assertWarnsRegex(DeprecationWarning, r"BaseCookie\.js_output"):
             self.assertEqual(C.js_output(['path']), fr"""
         <script type="text/javascript">
         <!-- begin hiding
-        document.cookie = atob("{expected_encoded_cookie}");
+        document.cookie = decodeURIComponent("{expected_encoded_cookie}");
         // end hiding -->
         </script>
         """)
@@ -376,13 +376,14 @@ class MorselTests(unittest.TestCase):
             self.assertEqual(
                 M.output(),
                 "Set-Cookie: %s=%s; Path=/foo" % (i, "%s_coded_val" % i))
-            expected_encoded_cookie = base64.b64encode(
-                ("%s=%s; Path=/foo" % (i, "%s_coded_val" % i)).encode("ascii")
-            ).decode('ascii')
+            expected_encoded_cookie = urllib.parse.quote(
+                "%s=%s; Path=/foo" % (i, "%s_coded_val" % i),
+                safe='', encoding='utf-8',
+            )
             expected_js_output = """
         <script type="text/javascript">
         <!-- begin hiding
-        document.cookie = atob("%s");
+        document.cookie = decodeURIComponent("%s");
         // end hiding -->
         </script>
         """ % (expected_encoded_cookie,)