Browse Source

Fixed #32712 -- Deprecated django.utils.baseconv module.

Hasan Ramezani 3 years ago
parent
commit
028f10fac6

+ 28 - 3
django/core/signing.py

@@ -40,13 +40,13 @@ import time
 import zlib
 
 from django.conf import settings
-from django.utils import baseconv
 from django.utils.crypto import constant_time_compare, salted_hmac
 from django.utils.encoding import force_bytes
 from django.utils.module_loading import import_string
 from django.utils.regex_helper import _lazy_re_compile
 
 _SEP_UNSAFE = _lazy_re_compile(r'^[A-z0-9-_=]*$')
+BASE62_ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
 
 
 class BadSignature(Exception):
@@ -59,6 +59,31 @@ class SignatureExpired(BadSignature):
     pass
 
 
+def b62_encode(s):
+    if s == 0:
+        return '0'
+    sign = '-' if s < 0 else ''
+    s = abs(s)
+    encoded = ''
+    while s > 0:
+        s, remainder = divmod(s, 62)
+        encoded = BASE62_ALPHABET[remainder] + encoded
+    return sign + encoded
+
+
+def b62_decode(s):
+    if s == '0':
+        return 0
+    sign = 1
+    if s[0] == '-':
+        s = s[1:]
+        sign = -1
+    decoded = 0
+    for digit in s:
+        decoded = decoded * 62 + BASE62_ALPHABET.index(digit)
+    return sign * decoded
+
+
 def b64_encode(s):
     return base64.urlsafe_b64encode(s).strip(b'=')
 
@@ -187,7 +212,7 @@ class Signer:
 class TimestampSigner(Signer):
 
     def timestamp(self):
-        return baseconv.base62.encode(int(time.time()))
+        return b62_encode(int(time.time()))
 
     def sign(self, value):
         value = '%s%s%s' % (value, self.sep, self.timestamp())
@@ -200,7 +225,7 @@ class TimestampSigner(Signer):
         """
         result = super().unsign(value)
         value, timestamp = result.rsplit(self.sep, 1)
-        timestamp = baseconv.base62.decode(timestamp)
+        timestamp = b62_decode(timestamp)
         if max_age is not None:
             if isinstance(max_age, datetime.timedelta):
                 max_age = max_age.total_seconds()

+ 10 - 0
django/utils/baseconv.py

@@ -1,3 +1,4 @@
+# RemovedInDjango50Warning
 # Copyright (c) 2010 Guilherme Gondim. All rights reserved.
 # Copyright (c) 2009 Simon Willison. All rights reserved.
 # Copyright (c) 2002 Drew Perttula. All rights reserved.
@@ -36,6 +37,15 @@ Sample usage::
   -1234
 
 """
+import warnings
+
+from django.utils.deprecation import RemovedInDjango50Warning
+
+warnings.warn(
+    'The django.utils.baseconv module is deprecated.',
+    category=RemovedInDjango50Warning,
+    stacklevel=2,
+)
 
 BASE2_ALPHABET = '01'
 BASE16_ALPHABET = '0123456789ABCDEF'

+ 2 - 0
docs/internals/deprecation.txt

@@ -17,6 +17,8 @@ details on these changes.
 
 * The ``SERIALIZE`` test setting will be removed.
 
+* The undocumented ``django.utils.baseconv`` module will be removed.
+
 .. _deprecation-removed-in-4.1:
 
 4.1

+ 2 - 0
docs/releases/4.0.txt

@@ -432,6 +432,8 @@ Miscellaneous
   :attr:`~django.test.TestCase.databases` with the
   :ref:`serialized_rollback <test-case-serialized-rollback>` option enabled.
 
+* The undocumented ``django.utils.baseconv`` module is deprecated.
+
 Features removed in 4.0
 =======================
 

+ 7 - 0
tests/signing/tests.py

@@ -195,3 +195,10 @@ class TestTimestampSigner(SimpleTestCase):
             self.assertEqual(signer.unsign(ts, max_age=datetime.timedelta(seconds=11)), value)
             with self.assertRaises(signing.SignatureExpired):
                 signer.unsign(ts, max_age=10)
+
+
+class TestBase62(SimpleTestCase):
+    def test_base62(self):
+        tests = [-10 ** 10, 10 ** 10, 1620378259, *range(-100, 100)]
+        for i in tests:
+            self.assertEqual(i, signing.b62_decode(signing.b62_encode(i)))

+ 8 - 3
tests/utils_tests/test_baseconv.py

@@ -1,10 +1,15 @@
 from unittest import TestCase
 
-from django.utils.baseconv import (
-    BaseConverter, base2, base16, base36, base56, base62, base64,
-)
+from django.test import ignore_warnings
+from django.utils.deprecation import RemovedInDjango50Warning
 
+with ignore_warnings(category=RemovedInDjango50Warning):
+    from django.utils.baseconv import (
+        BaseConverter, base2, base16, base36, base56, base62, base64,
+    )
 
+
+# RemovedInDjango50Warning
 class TestBaseConv(TestCase):
 
     def test_baseconv(self):