Skip to content

Commit e186012

Browse files
lorinkozsarahboyce
authored andcommitted
[5.0.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 9e97922. Backport of 0e94f29 from main.
1 parent 41d8ef1 commit e186012

File tree

6 files changed

+31
-7
lines changed

6 files changed

+31
-7
lines changed

django/utils/translation/trans_real.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ def get_supported_language_variant(lang_code, strict=False):
517517
# There is a generic variant under the maximum length accepted length.
518518
lang_code = lang_code[:index]
519519
else:
520-
raise ValueError("'lang_code' exceeds the maximum accepted length")
520+
raise LookupError(lang_code)
521521
# If 'zh-hant-tw' is not supported, try special fallback or subsequent
522522
# language codes i.e. 'zh-hant' and 'zh'.
523523
possible_lang_codes = [lang_code]

docs/ref/utils.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,7 +1114,7 @@ For a complete discussion on the usage of the following see the
11141114
``'es-ar'`` isn't.
11151115

11161116
``lang_code`` has a maximum accepted length of 500 characters. A
1117-
:exc:`ValueError` is raised if ``lang_code`` exceeds this limit and
1117+
:exc:`LookupError` is raised if ``lang_code`` exceeds this limit and
11181118
``strict`` is ``True``, or if there is no generic variant and ``strict``
11191119
is ``False``.
11201120

@@ -1126,10 +1126,10 @@ For a complete discussion on the usage of the following see the
11261126

11271127
Raises :exc:`LookupError` if nothing is found.
11281128

1129-
.. versionchanged:: 4.2.14
1129+
.. versionchanged:: 4.2.15
11301130

11311131
In older versions, ``lang_code`` values over 500 characters were
1132-
processed without raising a :exc:`ValueError`.
1132+
processed without raising a :exc:`LookupError`.
11331133

11341134
.. function:: to_locale(language)
11351135

docs/releases/4.2.15.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
===========================
2+
Django 4.2.15 release notes
3+
===========================
4+
5+
*Expected August 6, 2024*
6+
7+
Django 4.2.15 fixes a regression in 4.2.14.
8+
9+
Bugfixes
10+
========
11+
12+
* Fixed a regression in Django 4.2.14 that caused a crash in
13+
``LocaleMiddleware`` when processing a language code over 500 characters
14+
(:ticket:`35627`).

docs/releases/5.0.8.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ Bugfixes
1919
* Fixed a crash when creating a model with a ``Field.db_default`` and a
2020
``Meta.constraints`` constraint composed of ``__endswith``, ``__startswith``,
2121
or ``__contains`` lookups (:ticket:`35625`).
22+
23+
* Fixed a regression in Django 5.0.7 that caused a crash in
24+
``LocaleMiddleware`` when processing a language code over 500 characters
25+
(:ticket:`35627`).

docs/releases/index.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ versions of the documentation contain the release notes for any later releases.
4141
.. toctree::
4242
:maxdepth: 1
4343

44+
4.2.15
4445
4.2.14
4546
4.2.13
4647
4.2.12

tests/i18n/tests.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,14 +1673,13 @@ def test_get_supported_language_variant_real(self):
16731673
g("xyz")
16741674
with self.assertRaises(LookupError):
16751675
g("xy-zz")
1676-
msg = "'lang_code' exceeds the maximum accepted length"
16771676
with self.assertRaises(LookupError):
16781677
g("x" * LANGUAGE_CODE_MAX_LENGTH)
1679-
with self.assertRaisesMessage(ValueError, msg):
1678+
with self.assertRaises(LookupError):
16801679
g("x" * (LANGUAGE_CODE_MAX_LENGTH + 1))
16811680
# 167 * 3 = 501 which is LANGUAGE_CODE_MAX_LENGTH + 1.
16821681
self.assertEqual(g("en-" * 167), "en")
1683-
with self.assertRaisesMessage(ValueError, msg):
1682+
with self.assertRaises(LookupError):
16841683
g("en-" * 167, strict=True)
16851684
self.assertEqual(g("en-" * 30000), "en") # catastrophic test
16861685

@@ -1734,6 +1733,7 @@ def test_get_language_from_path_real(self):
17341733
("/i-mingo/", "i-mingo"),
17351734
("/kl-tunumiit/", "kl-tunumiit"),
17361735
("/nan-hani-tw/", "nan-hani-tw"),
1736+
(f"/{'a' * 501}/", None),
17371737
]
17381738
for path, language in tests:
17391739
with self.subTest(path=path):
@@ -2012,6 +2012,11 @@ def test_get_language_from_request(self):
20122012
lang = get_language_from_request(request)
20132013
self.assertEqual("bg", lang)
20142014

2015+
def test_get_language_from_request_code_too_long(self):
2016+
request = self.rf.get("/", headers={"accept-language": "a" * 501})
2017+
lang = get_language_from_request(request)
2018+
self.assertEqual("en-us", lang)
2019+
20152020
def test_get_language_from_request_null(self):
20162021
lang = trans_null.get_language_from_request(None)
20172022
self.assertEqual(lang, "en")

0 commit comments

Comments
 (0)