summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Peña <lorinkoz@gmail.com>2024-07-23 12:06:29 +0200
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2024-07-25 09:44:51 +0200
commit96a349740048ecd4746ac2f15751865219d445cf (patch)
treed37238f85da8c63deb8c7ea3eef5fa2e397cf0c5
parentc5d196a65264136ee6795356871a29f3d22ec52f (diff)
[4.2.x] Fixed #35627 -- Raised a LookupError rather than an unhandled ValueError in get_supported_language_variant().
LocaleMiddleware didn't handle the ValueError raised by get_supported_language_variant() when language codes were over 500 characters. Regression in 9e9792228a6bb5d6402a5d645bc3be4cf364aefb. Backport of 0e94f292cda632153f2b3d9a9037eb0141ae9c2e from main.
-rw-r--r--django/utils/translation/trans_real.py2
-rw-r--r--docs/ref/utils.txt6
-rw-r--r--docs/releases/4.2.15.txt14
-rw-r--r--docs/releases/index.txt1
-rw-r--r--tests/i18n/tests.py11
5 files changed, 27 insertions, 7 deletions
diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
index ce13d1e69c..6833b4bf7f 100644
--- a/django/utils/translation/trans_real.py
+++ b/django/utils/translation/trans_real.py
@@ -516,7 +516,7 @@ def get_supported_language_variant(lang_code, strict=False):
# There is a generic variant under the maximum length accepted length.
lang_code = lang_code[:index]
else:
- raise ValueError("'lang_code' exceeds the maximum accepted length")
+ raise LookupError(lang_code)
# If 'zh-hant-tw' is not supported, try special fallback or subsequent
# language codes i.e. 'zh-hant' and 'zh'.
possible_lang_codes = [lang_code]
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index 471a4b31eb..acf7afd4a7 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -1156,7 +1156,7 @@ For a complete discussion on the usage of the following see the
``'es-ar'`` isn't.
``lang_code`` has a maximum accepted length of 500 characters. A
- :exc:`ValueError` is raised if ``lang_code`` exceeds this limit and
+ :exc:`LookupError` is raised if ``lang_code`` exceeds this limit and
``strict`` is ``True``, or if there is no generic variant and ``strict``
is ``False``.
@@ -1168,10 +1168,10 @@ For a complete discussion on the usage of the following see the
Raises :exc:`LookupError` if nothing is found.
- .. versionchanged:: 4.2.14
+ .. versionchanged:: 4.2.15
In older versions, ``lang_code`` values over 500 characters were
- processed without raising a :exc:`ValueError`.
+ processed without raising a :exc:`LookupError`.
.. function:: to_locale(language)
diff --git a/docs/releases/4.2.15.txt b/docs/releases/4.2.15.txt
new file mode 100644
index 0000000000..a15eced1a3
--- /dev/null
+++ b/docs/releases/4.2.15.txt
@@ -0,0 +1,14 @@
+===========================
+Django 4.2.15 release notes
+===========================
+
+*Expected August 6, 2024*
+
+Django 4.2.15 fixes a regression in 4.2.14.
+
+Bugfixes
+========
+
+* Fixed a regression in Django 4.2.14 that caused a crash in
+ ``LocaleMiddleware`` when processing a language code over 500 characters
+ (:ticket:`35627`).
diff --git a/docs/releases/index.txt b/docs/releases/index.txt
index ff1c2e6532..62695714b7 100644
--- a/docs/releases/index.txt
+++ b/docs/releases/index.txt
@@ -26,6 +26,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1
+ 4.2.15
4.2.14
4.2.13
4.2.12
diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py
index 9b029d5992..a2a747f6ea 100644
--- a/tests/i18n/tests.py
+++ b/tests/i18n/tests.py
@@ -1889,14 +1889,13 @@ class MiscTests(SimpleTestCase):
g("xyz")
with self.assertRaises(LookupError):
g("xy-zz")
- msg = "'lang_code' exceeds the maximum accepted length"
with self.assertRaises(LookupError):
g("x" * LANGUAGE_CODE_MAX_LENGTH)
- with self.assertRaisesMessage(ValueError, msg):
+ with self.assertRaises(LookupError):
g("x" * (LANGUAGE_CODE_MAX_LENGTH + 1))
# 167 * 3 = 501 which is LANGUAGE_CODE_MAX_LENGTH + 1.
self.assertEqual(g("en-" * 167), "en")
- with self.assertRaisesMessage(ValueError, msg):
+ with self.assertRaises(LookupError):
g("en-" * 167, strict=True)
self.assertEqual(g("en-" * 30000), "en") # catastrophic test
@@ -1950,6 +1949,7 @@ class MiscTests(SimpleTestCase):
("/i-mingo/", "i-mingo"),
("/kl-tunumiit/", "kl-tunumiit"),
("/nan-hani-tw/", "nan-hani-tw"),
+ (f"/{'a' * 501}/", None),
]
for path, language in tests:
with self.subTest(path=path):
@@ -2228,6 +2228,11 @@ class CountrySpecificLanguageTests(SimpleTestCase):
lang = get_language_from_request(request)
self.assertEqual("bg", lang)
+ def test_get_language_from_request_code_too_long(self):
+ request = self.rf.get("/", headers={"accept-language": "a" * 501})
+ lang = get_language_from_request(request)
+ self.assertEqual("en-us", lang)
+
def test_get_language_from_request_null(self):
lang = trans_null.get_language_from_request(None)
self.assertEqual(lang, "en")